Repository: VictoriaMetrics/VictoriaMetrics
Pull request #3005 (2022-08-21 02:37:06)

Fix doc Cluster-VictoriaMetrics.md
Flags `-search.maxTagKeys` and `-search.maxTagValues` are present at vmstorage and not at vmselect
```
# ./vmselect-prod -h | egrep 'search.maxTagKeys|search.maxTagValues'
# ./vmstorage-prod -h | egrep 'search.maxTagKeys|search.maxTagValues'
  -search.maxTagKeys int
  -search.maxTagValues int
```


Patch:
diff --git a/README.md b/README.md
index 6d56e2674..60336bb68 100644
--- a/README.md
+++ b/README.md
@@ -610,8 +610,8 @@ For example, `/api/put?extra_label=foo=bar` would add `{foo="bar"}` label to all
 
 VictoriaMetrics supports the following handlers from [Prometheus querying API](https://prometheus.io/docs/prometheus/latest/querying/api/):
 
-* [/api/v1/query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries)
-* [/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries)
+* [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query)
+* [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query)
 * [/api/v1/series](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers)
 * [/api/v1/labels](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names)
 * [/api/v1/label/.../values](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values)
diff --git a/app/vmagent/README.md b/app/vmagent/README.md
index 7ae2666cb..efff2fb4d 100644
--- a/app/vmagent/README.md
+++ b/app/vmagent/README.md
@@ -178,7 +178,7 @@ See [the list of supported service discovery types for Prometheus scrape targets
 
 ## scrape_config enhancements
 
-`vmagent` supports the following additional options in `scrape_configs` section:
+`vmagent` supports the following additional options in [scrape_configs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs) section:
 
 * `headers` - a list of HTTP headers to send to scrape target with each scrape request. This can be used when the scrape target needs custom authorization and authentication. For example:
 
@@ -199,9 +199,12 @@ scrape_configs:
 * `relabel_debug: true` for enabling debug logging during relabeling of the discovered targets. See [these docs](#relabeling).
 * `metric_relabel_debug: true` for enabling debug logging during relabeling of the scraped metrics. See [these docs](#relabeling).
 
+See [scrape_configs docs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs) for more details on all the supported options.
+
+
 ## Loading scrape configs from multiple files
 
-`vmagent` supports loading scrape configs from multiple files specified in the `scrape_config_files` section of `-promscrape.config` file. For example, the following `-promscrape.config` instructs `vmagent` loading scrape configs from all the `*.yml` files under `configs` directory, from `single_scrape_config.yml` local file and from `https://config-server/scrape_config.yml` url:
+`vmagent` supports loading [scrape configs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs) from multiple files specified in the `scrape_config_files` section of `-promscrape.config` file. For example, the following `-promscrape.config` instructs `vmagent` loading scrape configs from all the `*.yml` files under `configs` directory, from `single_scrape_config.yml` local file and from `https://config-server/scrape_config.yml` url:
 
 ```yml
 scrape_config_files:
@@ -210,7 +213,7 @@ scrape_config_files:
 - https://config-server/scrape_config.yml
 ```
 
-Every referred file can contain arbitrary number of [supported scrape configs](#how-to-collect-metrics-in-prometheus-format). There is no need in specifying top-level `scrape_configs` section in these files. For example:
+Every referred file can contain arbitrary number of [supported scrape configs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs). There is no need in specifying top-level `scrape_configs` section in these files. For example:
 
 ```yml
 - job_name: foo
@@ -338,85 +341,94 @@ The following articles contain useful information about Prometheus relabeling:
 
 ## Relabeling enhancements
 
-VictoriaMetrics provides the following additional relabeling actions on top of standard actions from the [Prometheus relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config):
-
-* `replace_all` replaces all of the occurrences of `regex` in the values of `source_labels` with the `replacement` and stores the results in the `target_label`. For example, the following relabeling config replaces all the occurrences of `-` char in metric names with `_` char (e.g. `foo-bar-baz` metric name is transformed into `foo_bar_baz`):
+* The `replacement` option can refer arbitrary labels via {% raw %}`{{label_name}}`{% endraw %} placeholders. Such placeholders are substituted with the corresponding label value. For example, the following relabeling rule sets `instance-job` label value to `host123-foo` when applied to the metric with `{instance="host123",job="foo"}` labels:
 
+  {% raw %}
   ```yaml
-  - action: replace_all
-    source_labels: ["__name__"]
-    target_label: "__name__"
-    regex: "-"
-    replacement: "_"
+  - target_label: "instance-job"
+    replacement: "{{instance}}-{{job}}"
   ```
+  {% endraw %}
 
-* `labelmap_all` replaces all of the occurrences of `regex` in all the label names with the `replacement`. For example, the following relabeling config replaces all the occurrences of `-` char in all the label names with `_` char (e.g. `foo-bar-baz` label name is transformed into `foo_bar_baz`):
+* An optional `if` filter can be used for conditional relabeling. The `if` filter may contain arbitrary [time series selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). For example, the following relabeling rule drops metrics, which don't match `foo{bar="baz"}` series selector, while leaving the rest of metrics:
 
   ```yaml
-  - action: labelmap_all
-    regex: "-"
-    replacement: "_"
+  - action: keep
+    if: 'foo{bar="baz"}'
   ```
 
-* `keep_if_equal`: keeps the entry if all the label values from `source_labels` are equal, while dropping all the other entries. For example, the following relabeling config keeps targets if they contain equal values for `instance` and `host` labels, while dropping all the other targets:
+  This is equivalent to less clear Prometheus-compatible relabeling rule:
 
   ```yaml
-  - action: keep_if_equal
-    source_labels: ["instance", "host"]
+  - action: keep
+    source_labels: [__name__, bar]
+    regex: 'foo;baz'
   ```
 
-* `drop_if_equal`: drops the entry if all the label values from `source_labels` are equal, while keeping all the other entries. For example, the following relabeling config drops targets if they contain equal values for `instance` and `host` labels, while keeping all the other targets:
+* The `regex` value can be split into multiple lines for improved readability and maintainability. These lines are automatically joined with `|` char when parsed. For example, the following configs are equivalent:
 
   ```yaml
-  - action: drop_if_equal
-    source_labels: ["instance", "host"]
+  - action: keep_metrics
+    regex: "metric_a|metric_b|foo_.+"
   ```
 
-* `keep_metrics`: keeps all the metrics with names matching the given `regex`, while dropping all the other metrics. For example, the following relabeling config keeps metrics with `fo` and `bar` names, while dropping all the other metrics:
-
   ```yaml
   - action: keep_metrics
-    regex: "foo|bar"
+    regex:
+    - "metric_a"
+    - "metric_b"
+    - "foo_.+"
   ```
 
-* `drop_metrics`: drops all the metrics with names matching the given `regex`, while keeping all the other metrics. For example, the following relabeling config drops metrics with `foo` and `bar` names, while leaving all the other metrics:
+* VictoriaMetrics provides the following additional relabeling actions on top of standard actions from the [Prometheus relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config):
 
-  ```yaml
-  - action: drop_metrics
-    regex: "foo|bar"
-  ```
+  * `replace_all` replaces all of the occurrences of `regex` in the values of `source_labels` with the `replacement` and stores the results in the `target_label`. For example, the following relabeling config replaces all the occurrences of `-` char in metric names with `_` char (e.g. `foo-bar-baz` metric name is transformed into `foo_bar_baz`):
 
-* `graphite`: applies Graphite-style relabeling to metric name. See [these docs](#graphite-relabeling) for details.
+    ```yaml
+    - action: replace_all
+      source_labels: ["__name__"]
+      target_label: "__name__"
+      regex: "-"
+      replacement: "_"
+    ```
 
-The `regex` value can be split into multiple lines for improved readability and maintainability. These lines are automatically joined with `|` char when parsed. For example, the following configs are equivalent:
+  * `labelmap_all` replaces all of the occurrences of `regex` in all the label names with the `replacement`. For example, the following relabeling config replaces all the occurrences of `-` char in all the label names with `_` char (e.g. `foo-bar-baz` label name is transformed into `foo_bar_baz`):
 
-```yaml
-- action: keep_metrics
-  regex: "metric_a|metric_b|foo_.+"
-```
+    ```yaml
+    - action: labelmap_all
+      regex: "-"
+      replacement: "_"
+    ```
 
-```yaml
-- action: keep_metrics
-  regex:
-  - "metric_a"
-  - "metric_b"
-  - "foo_.+"
-```
+  * `keep_if_equal`: keeps the entry if all the label values from `source_labels` are equal, while dropping all the other entries. For example, the following relabeling config keeps targets if they contain equal values for `instance` and `host` labels, while dropping all the other targets:
 
-VictoriaMetrics components support an optional `if` filter in relabeling configs, which can be used for conditional relabeling. The `if` filter may contain arbitrary [time series selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). For example, the following relabeling rule drops metrics, which don't match `foo{bar="baz"}` series selector, while leaving the rest of metrics:
+    ```yaml
+    - action: keep_if_equal
+      source_labels: ["instance", "host"]
+    ```
 
-```yaml
-- action: keep
-  if: 'foo{bar="baz"}'
-```
+  * `drop_if_equal`: drops the entry if all the label values from `source_labels` are equal, while keeping all the other entries. For example, the following relabeling config drops targets if they contain equal values for `instance` and `host` labels, while keeping all the other targets:
 
-This is equivalent to less clear Prometheus-compatible relabeling rule:
+    ```yaml
+    - action: drop_if_equal
+      source_labels: ["instance", "host"]
+    ```
 
-```yaml
-- action: keep
-  source_labels: [__name__, bar]
-  regex: 'foo;baz'
-```
+  * `keep_metrics`: keeps all the metrics with names matching the given `regex`, while dropping all the other metrics. For example, the following relabeling config keeps metrics with `fo` and `bar` names, while dropping all the other metrics:
+
+    ```yaml
+    - action: keep_metrics
+      regex: "foo|bar"
+    ```
+
+  * `drop_metrics`: drops all the metrics with names matching the given `regex`, while keeping all the other metrics. For example, the following relabeling config drops metrics with `foo` and `bar` names, while leaving all the other metrics:
+
+    ```yaml
+    - action: drop_metrics
+      regex: "foo|bar"
+    ```
+
+  * `graphite`: applies Graphite-style relabeling to metric name. See [these docs](#graphite-relabeling) for details.
 
 ## Graphite relabeling
 
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 11bd31116..787376239 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -21,9 +21,10 @@ The following tip changes can be tested by building VictoriaMetrics components f
 
 * SECURITY: [vmalert](https://docs.victoriametrics.com/vmalert.html): do not expose `-remoteWrite.url`, `-remoteRead.url` and `-datasource.url` command-line flag values in logs and at `http://vmalert:8880/flags` page by default, since they may contain sensitive data such as auth keys. This aligns `vmalert` behaviour with [vmagent](https://docs.victoriametrics.com/vmagent.html), which doesn't expose `-remoteWrite.url` command-line flag value in logs and at `http://vmagent:8429/flags` page by default. Specify `-remoteWrite.showURL`, `-remoteRead.showURL` and `-datasource.showURL` command-line flags for showing values for the corresponding `-*.url` flags in logs. Thanks to @mble for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2965).
 
-* FEATURE: return shorter error messages to Grafana and to other clients requesting [/api/v1/query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries) and [/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) endpoints. This should simplify reading these errors by humans. The long error message with full context is still written to logs.
+* FEATURE: return shorter error messages to Grafana and to other clients requesting [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query) and [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query) endpoints. This should simplify reading these errors by humans. The long error message with full context is still written to logs.
 * FEATURE: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): reduce the amounts of logging at `vmstorage` when `vmselect` connects/disconnects to `vmstorage`.
 * FEATURE: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): improve performance for heavy queries on systems with many CPU cores.
+* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add ability to use {% raw %}`{{label_name}}`{% endraw %} placeholders in the `replacement` option of relabeling rules. This simplifies constructing label values from multiple existing label values. See [these docs](https://docs.victoriametrics.com/vmagent.html#relabeling-enhancements) for details.
 * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): generate additional per-target metrics - `scrape_series_limit`, `scrape_series_current` and `scrape_series_limit_samples_dropped` if series limit is set according to [these docs](https://docs.victoriametrics.com/vmagent.html#cardinality-limiter). This simplifies alerting on targets with the exceeded series limit. See [these docs](https://docs.victoriametrics.com/vmagent.html#automatically-generated-metrics) for details on these metrics.
 * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add support for MX record types in [dns_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dns_sd_configs) in the same way as Prometheus 2.38 [does](https://github.com/prometheus/prometheus/pull/10099).
 * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add `__meta_kubernetes_service_port_number` meta-label for `role: service` in [kubernetes_sd_configs](https://docs.victoriametrics.com/sd_configs.html#kubernetes_sd_configs) in the same way as Prometheus 2.38 [does](https://github.com/prometheus/prometheus/pull/11002).
@@ -142,7 +143,7 @@ scrape_configs:
 * FEATURE: expose additional histogram metrics at `http://victoriametrics:8428/metrics`, which may help understanding query workload:
 
   * `vm_rows_read_per_query` - the number of raw samples read per query.
-  * `vm_rows_scanned_per_query` - the number of raw samples scanned per query. This number can exceed `vm_rows_read_per_query` if `step` query arg passed to [/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) is smaller than the lookbehind window set in square brackets of [rollup function](https://docs.victoriametrics.com/MetricsQL.html#rollup-functions). For example, if `increase(some_metric[1h])` is executed with the `step=5m`, then the same raw samples on a hour time range are scanned `1h/5m=12` times. See [this article](https://valyala.medium.com/how-to-optimize-promql-and-metricsql-queries-85a1b75bf986) for details.
+  * `vm_rows_scanned_per_query` - the number of raw samples scanned per query. This number can exceed `vm_rows_read_per_query` if `step` query arg passed to [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query) is smaller than the lookbehind window set in square brackets of [rollup function](https://docs.victoriametrics.com/MetricsQL.html#rollup-functions). For example, if `increase(some_metric[1h])` is executed with the `step=5m`, then the same raw samples on a hour time range are scanned `1h/5m=12` times. See [this article](https://valyala.medium.com/how-to-optimize-promql-and-metricsql-queries-85a1b75bf986) for details.
   * `vm_rows_read_per_series` - the number of raw samples read per queried series.
   * `vm_series_read_per_query` - the number of series read per query.
 
@@ -169,7 +170,7 @@ scrape_configs:
 * BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): assume that the response is complete if `-search.denyPartialResponse` is enabled and up to `-replicationFactor - 1` `vmstorage` nodes are unavailable. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1767).
 * BUGFIX: [vmselect](https://docs.victoriametrics.com/#vmselect): update `vm_partial_results_total` metric labels to be consistent with `vm_requests_total` labels.
 * BUGFIX: accept tags without values when reading data in [DataDog format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-send-data-from-datadog-agent). Thanks to @PerGon for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2839).
-* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly pass the end of the selected time range to `time` query arg to [/api/v1/query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries) when displaying the requested data in JSON and table views. Previously the `time` query arg wasn't set, so `/api/v1/query` was always returning query results for the current time regardless of the selected time range. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2781).
+* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly pass the end of the selected time range to `time` query arg to [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query) when displaying the requested data in JSON and table views. Previously the `time` query arg wasn't set, so `/api/v1/query` was always returning query results for the current time regardless of the selected time range. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2781).
 * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): allow clicking on the suggestion from autocomplete list. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2804).
 * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): apply the selected time range in date picker only after clicking the `Apply` button. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2811).
 
diff --git a/docs/Cluster-VictoriaMetrics.md b/docs/Cluster-VictoriaMetrics.md
index 08bc75688..4b5d05f15 100644
--- a/docs/Cluster-VictoriaMetrics.md
+++ b/docs/Cluster-VictoriaMetrics.md
@@ -219,8 +219,8 @@ See [trobuleshooting docs](https://docs.victoriametrics.com/Troubleshooting.html
 - URLs for [Prometheus querying API](https://prometheus.io/docs/prometheus/latest/querying/api/): `http://<vmselect>:8481/select/<accountID>/prometheus/<suffix>`, where:
   - `<accountID>` is an arbitrary number identifying data namespace for the query (aka tenant)
   - `<suffix>` may have the following values:
-    - `api/v1/query` - performs [PromQL instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries).
-    - `api/v1/query_range` - performs [PromQL range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries).
+    - `api/v1/query` - performs [PromQL instant query](https://docs.victoriametrics.com/keyConcepts.html#instant-query).
+    - `api/v1/query_range` - performs [PromQL range query](https://docs.victoriametrics.com/keyConcepts.html#range-query).
     - `api/v1/series` - performs [series query](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers).
     - `api/v1/labels` - returns a [list of label names](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names).
     - `api/v1/label/<label_name>/values` - returns values for the given `<label_name>` according [to API](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values).
@@ -300,8 +300,47 @@ All the node types - `vminsert`, `vmselect` and `vmstorage` - may be updated via
 Send `SIGINT` signal to the corresponding process, wait until it finishes and then start new version
 with new configs.
 
-Cluster should remain in working state if at least a single node of each type remains available during
-the update process. See [cluster availability](#cluster-availability) section for details.
+There are the following cluster update / upgrade approaches exist:
+
+* `No downtime` strategy. Gracefully restart every node in the cluster one-by-one with the updated config / upgraded binary.
+
+  It is recommended restarting the nodes in the following order:
+
+  1. Restart `vmstorage` nodes.
+  2. Restart `vminsert` nodes.
+  3. Restart `vmselect` nodes.
+
+  This strategy allows upgrading the cluster without downtime if the following conditions are met:
+
+  - The cluster has at least a pair of nodes of each type - `vminsert`, `vmselect` and `vmstorage`,
+    so it can continue accept new data and serve incoming requests when a single node is temporary unavailable
+    during its restart. See [cluster availability docs](#cluster-availability) for details.
+  - The cluster has enough compute resources (CPU, RAM, network bandwidth, disk IO) for processing
+    the current workload when a single node of any type (`vminsert`, `vmselect` or `vmstorage`)
+    is temporarily unavailable during its restart.
+  - The updated config / upgraded binary is compatible with the remaining components in the cluster.
+    See the [CHANGELOG](https://docs.victoriametrics.com/CHANGELOG.html) for compatibility notes between different releases.
+
+  If at least a single condition isn't met, then the rolling restart may result in cluster unavailability
+  during the config update / version upgrade. In this case the following strategy is recommended.
+
+* `Minimum downtime` strategy:
+
+  1. Gracefully stop all the `vminsert` and `vmselect` nodes in parallel.
+  2. Gracefully restart all the `vmstorage` nodes in parallel.
+  3. Start all the `vminsert` and `vmselect` nodes in parallel.
+
+  The cluster is unavailable for data ingestion and querying when performing the steps above.
+  The downtime is minimized by restarting cluster nodes in parallel at every step above.
+  The `minimum downtime` strategy has the following benefits comparing to `no downtime` startegy:
+
+  - It allows performing config update / version upgrade with minimum disruption
+    when the previous config / version is incompatible with the new config / version.
+  - It allows perorming config update / version upgrade with minimum disruption
+    when the cluster has no enough compute resources (CPU, RAM, disk IO, network bandwidth)
+    for rolling upgrade.
+  - It allows minimizing the duration of config update / version ugprade for clusters with big number of nodes
+    of for clusters with big `vmstorage` nodes, which may take long time for graceful restart.
 
 ## Cluster availability
 
@@ -391,8 +430,8 @@ By default cluster components of VictoriaMetrics are tuned for an optimal resour
 - `-search.maxSamplesPerSeries` at `vmselect` limits the number of raw samples the query can process per each time series. `vmselect` sequentially processes raw samples per each found time series during the query. It unpacks raw samples on the selected time range per each time series into memory and then applies the given [rollup function](https://docs.victoriametrics.com/MetricsQL.html#rollup-functions). The `-search.maxSamplesPerSeries` command-line flag allows limiting memory usage at `vmselect` in the case when the query is executed on a time range, which contains hundreds of millions of raw samples per each located time series.
 - `-search.maxSamplesPerQuery` at `vmselect` limits the number of raw samples a single query can process. This allows limiting CPU usage at `vmselect` for heavy queries.
 - `-search.maxSeries` at `vmselect` limits the number of time series, which may be returned from [/api/v1/series](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers). This endpoint is used mostly by Grafana for auto-completion of metric names, label names and label values. Queries to this endpoint may take big amounts of CPU time and memory at `vmstorage` and `vmselect` when the database contains big number of unique time series because of [high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate). In this case it might be useful to set the `-search.maxSeries` to quite low value in order limit CPU and memory usage.
-- `-search.maxTagKeys` at `vmselect` limits the number of items, which may be returned from [/api/v1/labels](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names). This endpoint is used mostly by Grafana for auto-completion of label names. Queries to this endpoint may take big amounts of CPU time and memory at `vmstorage` and `vmselect` when the database contains big number of unique time series because of [high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate). In this case it might be useful to set the `-search.maxTagKeys` to quite low value in order to limit CPU and memory usage.
-- `-search.maxTagValues` at `vmselect` limits the number of items, which may be returned from [/api/v1/label/.../values](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values). This endpoint is used mostly by Grafana for auto-completion of label values. Queries to this endpoint may take big amounts of CPU time and memory at `vmstorage` and `vmselect` when the database contains big number of unique time series because of [high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate). In this case it might be useful to set the `-search.maxTagValues` to quite low value in order to limit CPU and memory usage.
+- `-search.maxTagKeys` at `vmstorage` limits the number of items, which may be returned from [/api/v1/labels](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names). This endpoint is used mostly by Grafana for auto-completion of label names. Queries to this endpoint may take big amounts of CPU time and memory at `vmstorage` and `vmselect` when the database contains big number of unique time series because of [high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate). In this case it might be useful to set the `-search.maxTagKeys` to quite low value in order to limit CPU and memory usage.
+- `-search.maxTagValues` at `vmstorage` limits the number of items, which may be returned from [/api/v1/label/.../values](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values). This endpoint is used mostly by Grafana for auto-completion of label values. Queries to this endpoint may take big amounts of CPU time and memory at `vmstorage` and `vmselect` when the database contains big number of unique time series because of [high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate). In this case it might be useful to set the `-search.maxTagValues` to quite low value in order to limit CPU and memory usage.
 - `-storage.maxDailySeries` at `vmstorage` can be used for limiting the number of time series seen per day.
 - `-storage.maxHourlySeries` at `vmstorage` can be used for limiting the number of [active time series](https://docs.victoriametrics.com/FAQ.html#what-is-an-active-time-series).
 
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 2c608f2f2..8c6b85bdc 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -104,6 +104,11 @@ VictoriaMetrics also [uses less RAM than Thanos components](https://github.com/t
 * QuestDB [supports a smaller range of popular data ingestion protocols](https://questdb.io/docs/develop/insert-data) compared to VictoriaMetrics (compare to [the list of supported data ingestion protocols for VictoriaMetrics](https://docs.victoriametrics.com/#how-to-import-time-series-data)).
 * [VictoriaMetrics supports backfilling (e.g. storing historical data) out of the box](https://docs.victoriametrics.com/#backfilling), while QuestDB provides [very limited support for backfilling](https://questdb.io/blog/2021/05/10/questdb-release-6-0-tsbs-benchmark#the-problem-with-out-of-order-data).
 
+## What is the difference between VictoriaMetrics and [Grafana Mimir](https://github.com/grafana/mimir)?
+
+Grafana Mimir is a [Cortex](https://github.com/cortexproject/cortex) fork, so it has the same differences
+as Cortex. See [what is the difference between VictoriaMetrics and Cortex](#what-is-the-difference-between-victoriametrics-and-cortex).
+
 ## What is the difference between VictoriaMetrics and [Cortex](https://github.com/cortexproject/cortex)?
 
 VictoriaMetrics is similar to Cortex in the following aspects:
@@ -330,10 +335,4 @@ The query engine may behave differently for some functions. Please see [this art
 
 Single-node VictoriaMetrics cannot be restarted / upgraded or downgraded without downtime, since it needs to be gracefully shut down and then started again. See [how to upgrade VictoriaMetrics](https://docs.victoriametrics.com/#how-to-upgrade-victoriametrics).
 
-[Cluster version of VictoriaMetrics](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html) can be restarted / upgraded / downgraded without downtime if the following conditions are met:
-
-* If every component of the cluster - `vminsert`, `vmselect` and `vmstorage` - has at least 2 instances.
-* If the cluster has enough compute resources (CPU, RAM, disk IO, network bandwidth) to perform rolling restart of all its components.
-* If the version used for upgrade / downgrade is compatible with the currently running version. The [CHANGELOG](https://docs.victoriametrics.com/CHANGELOG.html) contains compatibility notes for the published releases.
-
-See [updating / reconfiguring cluster nodes](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#updating--reconfiguring-cluster-nodes) for details on cluster upgrade.
+[Cluster version of VictoriaMetrics](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html) can be restarted / upgraded / downgraded without downtime according to [these instructions](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#updating--reconfiguring-cluster-nodes).
diff --git a/docs/README.md b/docs/README.md
index 6d56e2674..60336bb68 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -610,8 +610,8 @@ For example, `/api/put?extra_label=foo=bar` would add `{foo="bar"}` label to all
 
 VictoriaMetrics supports the following handlers from [Prometheus querying API](https://prometheus.io/docs/prometheus/latest/querying/api/):
 
-* [/api/v1/query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries)
-* [/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries)
+* [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query)
+* [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query)
 * [/api/v1/series](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers)
 * [/api/v1/labels](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names)
 * [/api/v1/label/.../values](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values)
diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md
index 601ffb18e..23299ccec 100644
--- a/docs/Single-server-VictoriaMetrics.md
+++ b/docs/Single-server-VictoriaMetrics.md
@@ -614,8 +614,8 @@ For example, `/api/put?extra_label=foo=bar` would add `{foo="bar"}` label to all
 
 VictoriaMetrics supports the following handlers from [Prometheus querying API](https://prometheus.io/docs/prometheus/latest/querying/api/):
 
-* [/api/v1/query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries)
-* [/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries)
+* [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query)
+* [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query)
 * [/api/v1/series](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers)
 * [/api/v1/labels](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names)
 * [/api/v1/label/.../values](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values)
diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md
index 2e05fa4b4..b6030bf24 100644
--- a/docs/Troubleshooting.md
+++ b/docs/Troubleshooting.md
@@ -45,8 +45,8 @@ If you see unexpected or unreliable query results from VictoriaMetrics, then try
    curl http://victoriametrics:8428/api/v1/export -d 'match[]=http_requests_total' -d 'start=...' -d 'end=...'
    ```
 
-   Note that responses returned from [/api/v1/query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries)
-   and from [/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) contain **evaluated** data
+   Note that responses returned from [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query)
+   and from [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query) contain **evaluated** data
    instead of raw samples stored in VictoriaMetrics. See [these docs](https://prometheus.io/docs/prometheus/latest/querying/basics/#staleness)
    for details.
 
diff --git a/docs/guides/migrate-from-influx.md b/docs/guides/migrate-from-influx.md
index a7f1d5dcc..2c29858c3 100644
--- a/docs/guides/migrate-from-influx.md
+++ b/docs/guides/migrate-from-influx.md
@@ -204,7 +204,7 @@ behavior by adding `fill(previous)` to the query.
 VictoriaMetrics fills the gaps on the graph assuming time series are always continious and not discrete.
 To limit the interval on which VictoriaMetrics will try to fill the gaps, set `-search.setLookbackToStep`
 command-line flag. This limits the gap filling to a single `step` interval passed to
-[/api/v1/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries).
+[/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query).
 This behavior is close to InfluxDB data model.
 
 
diff --git a/docs/keyConcepts.md b/docs/keyConcepts.md
index 858bd012f..f079eb31e 100644
--- a/docs/keyConcepts.md
+++ b/docs/keyConcepts.md
@@ -8,9 +8,7 @@ sort: 22
 
 ### What is a metric
 
-Simply put, `metric` - is a measure or observation of something. The measurement can be used to describe the process,
-compare it to other processes, perform some calculations with it, or even define events to trigger on reaching
-user-defined thresholds.
+Simply put, `metric` is a numeric measure or observation of something.
 
 The most common use-cases for metrics are:
 
@@ -19,8 +17,6 @@ The most common use-cases for metrics are:
 - observe or forecast trends;
 - trigger events (alerts) if the metric exceeds a threshold.
 
-Collecting and analyzing metrics provides advantages that are difficult to overestimate.
-
 ### Structure of a metric
 
 Let's start with an example. To track how many requests our application serves, we'll define a metric with the
@@ -28,16 +24,16 @@ name `requests_total`.
 
 You can be more specific here by saying `requests_success_total` (for only successful requests)
 or `request_errors_total` (for requests which failed). Choosing a metric name is very important and supposed to clarify
-what is actually measured to every person who reads it, just like variable names in programming.
+what is actually measured to every person who reads it, just like **variable names** in programming.
 
-Every metric can contain additional meta information in the form of label-value pairs:
+Every metric can contain additional meta-information in the form of label-value pairs:
 
 ```
 requests_total{path="/", code="200"} 
 requests_total{path="/", code="403"} 
 ```
 
-The meta-information (set of `labels` in curly braces) gives us a context for which `path` and with what `code`
+The meta-information - set of `labels` in curly braces - gives us a context for which `path` and with what `code`
 the `request` was served. Label-value pairs are always of a `string` type. VictoriaMetrics data model is schemaless,
 which means there is no need to define metric names or their labels in advance. User is free to add or change ingested
 metrics anytime.
@@ -51,59 +47,73 @@ requests_total{path="/", code="200"}
 
 #### Time series
 
-A combination of a metric name and its labels defines a `time series`. For
-example, `requests_total{path="/", code="200"}` and `requests_total{path="/", code="403"}`
-are two different time series.
+A combination of a metric name and its labels defines a `time series`. For example,
+`requests_total{path="/", code="200"}` and `requests_total{path="/", code="403"}`
+are two different time series because they have different values for `code` label.
 
-Number of time series has an impact on database resource usage. See
-also [What is an active time series?](https://docs.victoriametrics.com/FAQ.html#what-is-an-active-time-series)
-and  [What is high churn rate?](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate).
+The number of unique time series has an impact on database resource usage.
+See [what is an active time series](https://docs.victoriametrics.com/FAQ.html#what-is-an-active-time-series) and
+[what is high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate) docs for details.
 
 #### Cardinality
 
-The number of all unique label combinations for one metric defines its `cardinality`. For example, if `requests_total`
-has 3 unique `path` values and 5 unique `code` values, then its cardinality will be `3*5=15` of unique time series. If
-you add one more unique `path` value, cardinality will bump to `20`. See more in
-[What is cardinality](https://docs.victoriametrics.com/FAQ.html#what-is-high-cardinality).
+The number of unique [time series](#time-series) is named `cardinality`. Too big number of unique time series is named `high cardinality`.
+High cardinality may result in increased resource usage at VictoriaMetrics.
+See [these docs](https://docs.victoriametrics.com/FAQ.html#what-is-high-cardinality) for more details.
+
+#### Raw samples
 
-#### Data points
+Every unique time series may consist of arbitrary number of `(value, timestamp)` data points (aka `raw samples`) sorted by `timestamp`.
+The `value` is a [double-precision floating-point number](https://en.wikipedia.org/wiki/Double-precision_floating-point_format).
+The `timestamp` is a [unix timestamp](https://en.wikipedia.org/wiki/Unix_time) with millisecond precision.
 
-Every time series consists of `data points` (also called `samples`). A `data point` is value-timestamp pair associated
-with the specific series:
+Below is an example of a single raw sample
+in [Prometheus text exposition format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-based-format):
 
 ```
-requests_total{path="/", code="200"} <float64 value> <unixtimestamp>
+requests_total{path="/", code="200"} 123 4567890
 ```
 
-In VictoriaMetrics data model, data point's value is always of type `float64`. And timestamp is unix time with
-milliseconds precision. Each series can contain an infinite number of data points.
+- The `requests_total{path="/", code="200"}` identifies the associated time series for the given sample.
+- The `123` is a sample value.
+- The `4567890` is an optional timestamp for the sample. If it is missing,
+  then the current timestamp is used when storing the sample in VictoriaMetrics.
 
 ### Types of metrics
 
-Internally, VictoriaMetrics does not have a notion of a metric type. All metrics are the same. The concept of a metric
+Internally, VictoriaMetrics does not have the notion of a metric type. The concept of a metric
 type exists specifically to help users to understand how the metric was measured. There are 4 common metric types.
 
 #### Counter
 
-Counter metric type is a [monotonically increasing counter](https://en.wikipedia.org/wiki/Monotonic_function)
-used for capturing a number of events. It represents a cumulative metric whose value never goes down and always shows
-the current number of captured events. In other words, `counter` always shows the number of observed events since the
-application has started. In programming, `counter` is a variable that you **increment** each time something happens.
+Counter is a metric, which counts some events. Its value increases or stays the same over time.
+It cannot decrease in general case. The only exception is e.g. `counter reset`,
+when the metric resets to zero. The `counter reset` can occur when the service, which exposes the counter, restarts.
+So, the `counter` metric shows the number of observed events since the service start.
+
+In programming, `counter` is a variable that you **increment** each time something happens.
 
 {% include img.html href="keyConcepts_counter.png" %}
 
-`vm_http_requests_total` is a typical example of a counter - a metric which only grows. The interpretation of a graph
-above is that time series
-`vm_http_requests_total{instance="localhost:8428", job="victoriametrics", path="api/v1/query_range"}`
+`vm_http_requests_total` is a typical example of a counter. The interpretation of a graph
+above is that time series `vm_http_requests_total{instance="localhost:8428", job="victoriametrics", path="api/v1/query_range"}`
 was rapidly changing from 1:38 pm to 1:39 pm, then there were no changes until 1:41 pm.
 
-Counter is used for measuring a number of events, like a number of requests, errors, logs, messages, etc. The most
-common [MetricsQL](#metricsql) functions used with counters are:
+Counter is used for measuring the number of events, like the number of requests, errors, logs, messages, etc.
+The most common [MetricsQL](#metricsql) functions used with counters are:
 
-* [rate](https://docs.victoriametrics.com/MetricsQL.html#rate) - calculates the speed of metric's change. For
-  example, `rate(requests_total)` will show how many requests are served per second;
+* [rate](https://docs.victoriametrics.com/MetricsQL.html#rate) - calculates the average per-second speed of metric's change.
+  For example, `rate(requests_total)` shows how many requests are served per second on average;
 * [increase](https://docs.victoriametrics.com/MetricsQL.html#increase) - calculates the growth of a metric on the given
-  time period. For example, `increase(requests_total[1h])` will show how many requests were served over `1h` interval.
+  time period specified in square brackets.
+  For example, `increase(requests_total[1h])` shows the number of requests served over the last hour.
+
+It is OK to have fractional counters. For example, `request_duration_seconds_sum` counter may sum durations of all the requests.
+Every duration may have fractional value in seconds, e.g. `0.5` seconds. So the cumulative sum of all the request durations
+may be fractional too.
+
+It is recommended to put `_total`, `_sum` or `_count` suffix to `counter` metric names, so such metrics can be easily differentiated
+by humans from other metric types.
 
 #### Gauge
 
@@ -111,8 +121,8 @@ Gauge is used for measuring a value that can go up and down:
 
 {% include img.html href="keyConcepts_gauge.png" %}
 
-The metric `process_resident_memory_anon_bytes` on the graph shows the number of bytes of memory used by the application
-during the runtime. It is changing frequently, going up and down showing how the process allocates and frees the memory.
+The metric `process_resident_memory_anon_bytes` on the graph shows memory usage of the application at every given time.
+It is changing frequently, going up and down showing how the process allocates and frees the memory.
 In programming, `gauge` is a variable to which you **set** a specific value as it changes.
 
 Gauge is used in the following scenarios:
@@ -120,18 +130,21 @@ Gauge is used in the following scenarios:
 * measuring temperature, memory usage, disk usage etc;
 * storing the state of some process. For example, gauge `config_reloaded_successful` can be set to `1` if everything is
   good, and to `0` if configuration failed to reload;
-* storing the timestamp when event happened. For example, `config_last_reload_success_timestamp_seconds`
-  can store the timestamp of the last successful configuration relaod.
+* storing the timestamp when the event happened. For example, `config_last_reload_success_timestamp_seconds`
+  can store the timestamp of the last successful configuration reload.
 
-The most common [MetricsQL](#metricsql)
-functions used with gauges are [aggregation and grouping functions](#aggregation-and-grouping-functions).
+The most common [MetricsQL](#metricsql) functions used with gauges are [aggregation functions](#aggregation-and-grouping-functions)
+and [rollup functions](https://docs.victoriametrics.com/MetricsQL.html#rollup-functions).
 
 #### Histogram
 
-Histogram is a set of [counter](#counter) metrics with different labels for tracking the dispersion
-and [quantiles](https://prometheus.io/docs/practices/histograms/#quantiles) of the observed value. For example, in
-VictoriaMetrics we track how many rows is processed per query using the histogram with the
-name `vm_rows_read_per_query`. The exposition format for this histogram has the following form:
+Historgram is a set of [counter](#counter) metrics with different `vmrange` or `le` labels.
+The `vmrange` or `le` labels define measurement boundaries of a particular bucket.
+When the observed measurement hits a particular bucket, then the corresponding counter is incremented.
+
+Histogram buckets usually have `_bucket` suffix in their names.
+For example, VictoriaMetrics tracks the distribution of rows processed per query with the `vm_rows_read_per_query` histogram.
+The exposition format for this histogram has the following form:
 
 ```
 vm_rows_read_per_query_bucket{vmrange="4.084e+02...4.642e+02"} 2
@@ -143,7 +156,47 @@ vm_rows_read_per_query_sum 15582
 vm_rows_read_per_query_count 11
 ```
 
-In practice, histogram `vm_rows_read_per_query` may be used in the following way:
+The `vm_rows_read_per_query_bucket{vmrange="4.084e+02...4.642e+02"} 2` line means
+that there were 2 queries with the number of rows in the range `(408.4 - 464.2]`
+since the last VictoriaMetrics start.
+
+The counters ending with `_bucket` suffix allow estimating arbitrary percentile
+for the observed measurement with the help of [histogram_quantile](https://docs.victoriametrics.com/MetricsQL.html#histogram_quantile)
+function. For example, the following query returns the estimated 99th percentile
+on the number of rows read per each query during the last hour (see `1h` in square brackets):
+
+```metricsql
+histogram_quantile(0.99, sum(increase(vm_rows_read_per_query_bucket[1h])) by (vmrange))
+```
+
+This query works in the following way:
+
+1. The `increase(vm_rows_read_per_query_bucket[1h])` calculates per-bucket per-instance
+   number of events over the last hour.
+
+2. The `sum(...) by (vmrange)` calculates per-bucket events by summing per-instance buckets
+   with the same `vmrange` values.
+
+3. The `histogram_quantile(0.99, ...)` calculates 99th percentile over `vmrange` buckets returned at the step 2.
+
+Histogram metric type exposes two additional counters ending with `_sum` and `_count` suffixes:
+
+- the `vm_rows_read_per_query_sum` is a sum of all the observed measurements,
+  e.g. the sum of rows served by all the queries since the last VictoriaMetrics start.
+
+- the `vm_rows_read_per_query_count` is the total number of observed events,
+  e.g. the total number of observed queries since the last VictoriaMetrics start.
+
+These counters allow calculating the average measurement value on a particular lookbehind window.
+For example, the following query calculates the average number of rows read per query
+during the last 5 minutes (see `5m` in square brackets):
+
+```metricsql
+increase(vm_rows_read_per_query_sum[5m]) / increase(vm_rows_read_per_query_count[5m])
+```
+
+The `vm_rows_read_per_query` histogram may be used in Go application in the following way
+by using the [github.com/VictoriaMetrics/metrics](https://github.com/VictoriaMetrics/metrics) package:
 
 ```go
 // define the histogram
@@ -157,9 +210,8 @@ for _, query := range queries {
 
 Now let's see what happens each time when `rowsReadPerQuery.Update` is called:
 
-* counter `vm_rows_read_per_query_sum` increments by value of `len(query.Rows)` expression and accounts for
-  total sum of all observed values;
-* counter `vm_rows_read_per_query_count` increments by 1 and accounts for total number of observations;
+* counter `vm_rows_read_per_query_sum` is incremented by value of `len(query.Rows)` expression;
+* counter `vm_rows_read_per_query_count` increments by 1;
 * counter `vm_rows_read_per_query_bucket` gets incremented only if observed value is within the
   range (`bucket`) defined in `vmrange`.
 
@@ -169,7 +221,10 @@ and calculating [quantiles](https://prometheus.io/docs/practices/histograms/#qua
 
 {% include img.html href="keyConcepts_histogram.png" %}
 
-Histograms are usually used for measuring latency, sizes of elements (batch size, for example) etc. There are two
+Grafana doesn't understand buckets with `vmrange` labels, so the [prometheus_buckets](https://docs.victoriametrics.com/MetricsQL.html#prometheus_buckets)
+function must be used for converting buckets with `vmrange` labels to buckets with `le` labels before building heatmaps in Grafana.
+
+Histograms are usually used for measuring the distribution of latency, sizes of elements (batch size, for example) etc. There are two
 implementations of a histogram supported by VictoriaMetrics:
 
 1. [Prometheus histogram](https://prometheus.io/docs/practices/histograms/). The canonical histogram implementation
@@ -178,9 +233,9 @@ implementations of a histogram supported by VictoriaMetrics:
    histogram requires a user to define ranges (`buckets`) statically.
 2. [VictoriaMetrics histogram](https://valyala.medium.com/improving-histogram-usability-for-prometheus-and-grafana-bc7e5df0e350)
    supported by [VictoriaMetrics/metrics](https://github.com/VictoriaMetrics/metrics) instrumentation library.
-   Victoriametrics histogram automatically adjusts buckets, so users don't need to think about them.
+   Victoriametrics histogram automatically handles bucket boundaries, so users don't need to think about them.
 
-Histograms aren't trivial to learn and use. We recommend reading the following articles before you start:
+We recommend reading the following articles before you start using histograms:
 
 1. [Prometheus histogram](https://prometheus.io/docs/concepts/metric_types/#histogram)
 2. [Histograms and summaries](https://prometheus.io/docs/practices/histograms/)
@@ -189,9 +244,9 @@ Histograms aren't trivial to learn and use. We recommend reading the following a
 
 #### Summary
 
-Summary is quite similar to [histogram](#histogram) and is used for
-[quantiles](https://prometheus.io/docs/practices/histograms/#quantiles) calculations. The main difference to histograms
-is that calculations are made on the client-side, so metrics exposition format already contains pre-calculated
+Summary metric type is quite similar to [histogram](#histogram) and is used for
+[quantiles](https://prometheus.io/docs/practices/histograms/#quantiles) calculations. The main difference
+is that calculations are made on the client-side, so metrics exposition format already contains pre-defined
 quantiles:
 
 ```
@@ -208,90 +263,86 @@ The visualisation of summaries is pretty straightforward:
 
 {% include img.html href="keyConcepts_summary.png" %}
 
-Such an approach makes summaries easier to use but also puts significant limitations - summaries can't be aggregated.
-The [histogram](#histogram) exposes the raw values via counters. It means a user can aggregate these counters for
-different metrics (for example, for metrics with different `instance` label) and **then calculate quantiles**. For
-summary, quantiles are already calculated, so
-they [can't be aggregated](https://latencytipoftheday.blogspot.de/2014/06/latencytipoftheday-you-cant-average.html)
-with other metrics.
+Such an approach makes summaries easier to use but also puts significant limitations comparing to [histograms](#histogram):
 
-Summaries are usually used for measuring latency, sizes of elements (batch size, for example) etc. But taking into
-account the limitation mentioned above.
+- It is impossible to calculate quantile over multiple summary metrics, e.g. `sum(go_gc_duration_seconds{quantile="0.75"})`,
+  `avg(go_gc_duration_seconds{quantile="0.75"})` or `max(go_gc_duration_seconds{quantile="0.75"})`
+  won't return the expected 75th percentile over `go_gc_duration_seconds` metrics collected from multiple instances
+  of the application. See [this article](https://latencytipoftheday.blogspot.de/2014/06/latencytipoftheday-you-cant-average.html) for details.
+
+- It is impossible to calculate quantiles other than the already pre-calculated quantiles.
+
+- It is impossible to calculate quantiles for measurements collected over arbitrary time range. Usually `summary`
+  quantiles are calculated over a fixed time range such as the last 5 minutes.
+
+Summaries are usually used for tracking the pre-defined percentiles for latency, sizes of elements (batch size, for example) etc.
 
 ### Instrumenting application with metrics
 
-As was said at the beginning of the section [Types of metrics](#types-of-metrics), metric type defines how it was
-measured. VictoriaMetrics TSDB doesn't know about metric types, all it sees are labels, values, and timestamps. And what
-are these metrics, what do they measure, and how - all this depends on the application which emits them.
+As was said at the beginning of the [types of metrics](#types-of-metrics) section, metric type defines how it was
+measured. VictoriaMetrics TSDB doesn't know about metric types, all it sees are metric names, labels, values, and timestamps.
+What are these metrics, what do they measure, and how - all this depends on the application which emits them.
 
-To instrument your application with metrics compatible with VictoriaMetrics TSDB we recommend
-using [VictoriaMetrics/metrics](https://github.com/VictoriaMetrics/metrics) instrumentation library. See more about how
-to use it on example of
-[How to monitor Go applications with VictoriaMetrics](https://victoriametrics.medium.com/how-to-monitor-go-applications-with-victoriametrics-c04703110870)
-article.
+To instrument your application with metrics compatible with VictoriaMetrics we recommend
+using [github.com/VictoriaMetrics/metrics](https://github.com/VictoriaMetrics/metrics) package.
+See more details on how to use it in [this article](https://victoriametrics.medium.com/how-to-monitor-go-applications-with-victoriametrics-c04703110870).
 
-VictoriaMetrics is also compatible with
-Prometheus [client libraries for metrics instrumentation](https://prometheus.io/docs/instrumenting/clientlibs/).
+VictoriaMetrics is also compatible with [Prometheus client libraries for metrics instrumentation](https://prometheus.io/docs/instrumenting/clientlibs/).
 
 #### Naming
 
-We recommend following [naming convention introduced by Prometheus](https://prometheus.io/docs/practices/naming/). There
-are no strict (except allowed chars) restrictions and any metric name would be accepted by VictoriaMetrics. But
-convention will help to keep names meaningful, descriptive and clear to other people. Following convention is a good
-practice.
+We recommend following [Prometheus naming convention for metrics](https://prometheus.io/docs/practices/naming/). There
+are no strict restrictions, so any metric name and labels are be accepted by VictoriaMetrics.
+But the convention helps to keep names meaningful, descriptive and clear to other people.
+Following convention is a good practice.
 
 #### Labels
 
-Every metric can contain an arbitrary number of label names. The good practice is to keep this number limited.
-Otherwise, it would be difficult to use or plot on the graphs. By default, VictoriaMetrics limits the number of labels
-per series to `30` and drops all excessive labels. This limit can be changed via `-maxLabelsPerTimeseries` flag.
+Every measurement can contain an arbitrary number of `key="value"` labels. The good practice is to keep this number limited.
+Otherwise, it would be difficult to deal with measurements containing big number of labels.
+By default, VictoriaMetrics limits the number of labels per measurement to `30` and drops other labels.
+This limit can be changed via `-maxLabelsPerTimeseries` command-line flag if necessary (but this isn't recommended).
 
 Every label value can contain arbitrary string value. The good practice is to use short and meaningful label values to
 describe the attribute of the metric, not to tell the story about it. For example, label-value pair
-`environment=prod` is ok, but `log_message=long log message with a lot of details...` is not ok. By default,
-VcitoriaMetrics limits label's value size with 16kB. This limit can be changed via `-maxLabelValueLen` flag.
+`environment="prod"` is ok, but `log_message="long log message with a lot of details..."` is not ok. By default,
+VcitoriaMetrics limits label's value size with 16kB. This limit can be changed via `-maxLabelValueLen` command-line flag.
 
-It is very important to control the max number of unique label values since it defines the number
-of [time series](#time-series). Try to avoid using volatile values such as session ID or query ID in label values to
+It is very important to keep under control the number of unique label values, since every unique label value
+leads to a new [time series](#time-series). Try to avoid using volatile label values such as session ID or query ID in order to
 avoid excessive resource usage and database slowdown.
 
 ## Write data
 
-There are two main models in monitoring for data collection: [push](#push-model) and [pull](#pull-model). Both are used
-in modern monitoring and both are supported by VictoriaMetrics.
+VictoriaMetrics supports both models used in modern monitoring applications: [push](#push-model) and [pull](#pull-model).
 
 ### Push model
 
-Push model is a traditional model of the client sending data to the server:
+Client regularly sends the collected metrics to the server in push model:
 
 {% include img.html href="keyConcepts_push_model.png" %}
 
-The client (application) decides when and where to send/ingest its metrics. VictoriaMetrics supports following protocols
-for ingesting:
+The client (application) decides when and where to send its metrics. VictoriaMetrics supports the following protocols
+for data ingestion (aka `push protocols`):
 
 * [Prometheus remote write API](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#prometheus-setup).
-* [Prometheus exposition format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-prometheus-exposition-format)
-  .
+* [Prometheus text exposition format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-prometheus-exposition-format).
 * [InfluxDB line protocol](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf)
   over HTTP, TCP and UDP.
 * [Graphite plaintext protocol](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-send-data-from-graphite-compatible-agents-such-as-statsd)
   with [tags](https://graphite.readthedocs.io/en/latest/tags.html#carbon).
-* [OpenTSDB put message](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#sending-data-via-telnet-put-protocol)
-  .
-* [HTTP OpenTSDB /api/put requests](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#sending-opentsdb-data-via-http-apiput-requests)
-  .
-* [JSON line format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-json-line-format)
-  .
+* [OpenTSDB put message](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#sending-data-via-telnet-put-protocol).
+* [HTTP OpenTSDB /api/put requests](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#sending-opentsdb-data-via-http-apiput-requests).
+* [JSON line format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-json-line-format).
 * [Arbitrary CSV data](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-csv-data).
-* [Native binary format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-native-format)
-  .
+* [Native binary format](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-native-format).
 
 All the protocols are fully compatible with VictoriaMetrics [data model](#data-model) and can be used in production.
-There are no officially supported clients by VictoriaMetrics team for data ingestion. We recommend choosing from already
-existing clients compatible with the listed above protocols
-(like [Telegraf](https://github.com/influxdata/telegraf)
-for [InfluxDB line protocol](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf))
-.
+We recommend using the [github.com/VictoriaMetrics/metrics](https://github.com/VictoriaMetrics/metrics) package
+for pushing application metrics to VictoriaMetrics.
+It is also possible to use already existing clients compatible with the protocols listed above
+like [Telegraf](https://github.com/influxdata/telegraf)
+for [InfluxDB line protocol](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf).
 
 Creating custom clients or instrumenting the application for metrics writing is as easy as sending a POST request:
 
@@ -299,28 +350,28 @@ Creating custom clients or instrumenting the application for metrics writing is
 curl -d '{"metric":{"__name__":"foo","job":"node_exporter"},"values":[0,1,2],"timestamps":[1549891472010,1549891487724,1549891503438]}' -X POST 'http://localhost:8428/api/v1/import'
 ```
 
-It is allowed to push/write metrics
-to [Single-server-VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html),
-[cluster component vminsert](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#architecture-overview)
-and [vmagent](https://docs.victoriametrics.com/vmagent.html).
+It is allowed to push/write metrics to [single-node VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html),
+to [cluster component vminsert](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#architecture-overview)
+and to [vmagent](https://docs.victoriametrics.com/vmagent.html).
 
 The pros of push model:
 
-* application decides how and when to send data;
-* with a batch size of which size, at which rate;
-* with which retry logic;
-* simpler security management, the only access needed for the application is the access to the TSDB.
+* Simpler configuration at VictoriaMetrics side - there is no need to configure VictoriaMetrics with locations of the monitored applications.
+  There is no need in complex [service discovery schemes](https://docs.victoriametrics.com/sd_configs.html).
+* Simpler security setup - there is no need to set up access from VictoriaMetrics to each monitored application.
 
 See [Foiled by the Firewall: A Tale of Transition From Prometheus to VictoriaMetrics](https://www.percona.com/blog/2020/12/01/foiled-by-the-firewall-a-tale-of-transition-from-prometheus-to-victoriametrics/)
 elaborating more on why Percona switched from pull to push model.
 
 The cons of push protocol:
 
-* it requires applications to be more complex, since they need to be responsible for metrics delivery;
-* applications need to be aware of monitoring systems;
-* using a monitoring system it is hard to tell whether the application went down or just stopped sending metrics for a
-  different reason;
-* applications can overload the monitoring system by pushing too many metrics.
+* Increased configuration complexity for monitored applications.
+  Every application needs te be individually configured with the address of the monitoring system
+  for metrics delivery. It also needs to be configured with the interval between metric pushes
+  and the strategy on metric delivery failure.
+* Non-trivial setup for metrics' delivery into multiple monitoring systems.
+* It may be hard to tell whether the application went down or just stopped sending metrics for a different reason.
+* Applications can overload the monitoring system by pushing metrics at too short intervals.
 
 ### Pull model
 
@@ -330,86 +381,85 @@ and where to pull metrics from:
 {% include img.html href="keyConcepts_pull_model.png" %}
 
 In pull model, the monitoring system needs to be aware of all the applications it needs to monitor. The metrics are
-scraped (pulled) with fixed intervals via HTTP protocol.
+scraped (pulled) from the known applications (aka `scrape targets`) via HTTP protocol on a regular basis (aka `scrape_interval`).
 
-For metrics scraping VictoriaMetrics
-supports [Prometheus exposition format](https://docs.victoriametrics.com/#how-to-scrape-prometheus-exporters-such-as-node-exporter)
-and needs to be configured with `-promscrape.config` flag pointing to the file with scrape configuration. This
-configuration may include list of static `targets` (applications or services)
-or `targets` discovered via various service discoveries.
+VictoriaMetrics supports discovering Prometheus-compatible targets and scraping metrics from them in the same way as Prometheus does -
+see [these docs](https://docs.victoriametrics.com/#how-to-scrape-prometheus-exporters-such-as-node-exporter).
 
-Metrics scraping is supported
-by [Single-server-VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html)
-and [vmagent](https://docs.victoriametrics.com/vmagent.html).
+Metrics scraping is supported by [single-node VictoriaMetrics](https://docs.victoriametrics.com/#how-to-scrape-prometheus-exporters-such-as-node-exporter)
+and by [vmagent](https://docs.victoriametrics.com/vmagent.html).
 
 The pros of the pull model:
 
-* monitoring system decides how and when to scrape data, so it can't be overloaded;
-* applications aren't aware of the monitoring system and don't need to implement the logic for delivering metrics;
-* the list of all monitored targets belongs to the monitoring system and can be quickly checked;
-* easy to detect faulty or crashed services when they don't respond.
+* Easier to debug - VictoriaMetrics knows about all the monitored applications (aka `scrape targets`).
+  The `up == 0` query instantly shows unavailable scrape targets.
+  The actual information about scrape targets is available at `http://victoriametrics:8428/targets` and `http://vmagent:8429/targets`.
+* Monitoring system controls the frequency of metrics' scrape, so it is easier to control its' load.
+* Applications aren't aware of the monitoring system and don't need to implement the logic for metrics' delivery.
 
 The cons of the pull model:
 
-* monitoring system needs access to applications it monitors;
-* the frequency at which metrics are collected depends on the monitoring system.
+* Harder security setup - monitoring system needs have access to applications it monitors.
+* Pull model needs non-trivial [service discovery schemes](https://docs.victoriametrics.com/sd_configs.html).
 
 ### Common approaches for data collection
 
-VictoriaMetrics supports both [Push](#push-model) and [Pull](#pull-model)
-models for data collection. Many installations are using exclusively one or second model, or both at once.
+VictoriaMetrics supports both [push](#push-model) and [pull](#pull-model)
+models for data collection. Many installations use exclusively one of these models, or both at once.
 
 The most common approach for data collection is using both models:
 
 {% include img.html href="keyConcepts_data_collection.png" %}
 
 In this approach the additional component is used - [vmagent](https://docs.victoriametrics.com/vmagent.html). Vmagent is
-a lightweight agent whose main purpose is to collect and deliver metrics. It supports all the same mentioned protocols
-and approaches mentioned for both data collection models.
-
-The basic setup for using VictoriaMetrics and vmagent for monitoring is described in example
-of [docker-compose manifest](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/deployment/docker). In this
-example,
-vmagent [scrapes a list of targets](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/prometheus.yml)
-and [forwards collected data to VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/9d7da130b5a873be334b38c8d8dec702c9e8fac5/deployment/docker/docker-compose.yml#L15)
-. VictoriaMetrics is then used as
-a [datasource for Grafana](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/provisioning/datasources/datasource.yml)
+a lightweight agent whose main purpose is to collect, filter, relabel and deliver metrics to VictoriaMetrics.
+It supports all [push](#push-model) and [pull](#pull-model) protocols mentioned above.
+
+The basic monitoring setup of VictoriaMetrics and vmagent is described
+in the [example docker-compose manifest](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/deployment/docker).
+In this example vmagent [scrapes a list of targets](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/prometheus.yml)
+and [forwards collected data to VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/9d7da130b5a873be334b38c8d8dec702c9e8fac5/deployment/docker/docker-compose.yml#L15).
+VictoriaMetrics is then used as a [datasource for Grafana](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/provisioning/datasources/datasource.yml)
 installation for querying collected data.
 
-VictoriaMetrics components allow building more advanced topologies. For example, vmagents pushing metrics from separate
-datacenters to the central VictoriaMetrics:
+VictoriaMetrics components allow building more advanced topologies. For example, vmagents can push metrics from separate datacenters to the central VictoriaMetrics:
 
 {% include img.html href="keyConcepts_two_dcs.png" %}
 
-VictoriaMetrics in example may
-be [Single-server-VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html)
-or [VictoriaMetrics Cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html). Vmagent also allows to
-fan-out the same data to multiple destinations.
+VictoriaMetrics in this example the may be either [single-node VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html)
+or [VictoriaMetrics Cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html). Vmagent also allows
+[replicating the same data to multiple destinations](https://docs.victoriametrics.com/vmagent.html#replication-and-high-availability).
 
 ## Query data
 
 VictoriaMetrics provides
 an [HTTP API](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#prometheus-querying-api-usage)
 for serving read queries. The API is used in various integrations such as
-[Grafana](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#grafana-setup). The same API is also used
-by
+[Grafana](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#grafana-setup). The same API is also used by
 [VMUI](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#vmui) - graphical User Interface for querying
 and visualizing metrics.
 
-The API consists of two main handlers: [instant](#instant-query) and [range queries](#range-query).
+The API consists of two main handlers for serving [instant queries](#instant-query) and [range queries](#range-query).
 
 ### Instant query
 
-Instant query executes the query expression at the given moment of time:
+Instant query executes the query expression at the given timestamp:
 
 ```
-GET | POST /api/v1/query
+GET | POST /api/v1/query?query=...&time=...&step=...
+```
 
 Params:
-query - MetricsQL expression, required
-time - when (rfc3339 | unix_timestamp) to evaluate the query. If omitted, the current timestamp is used
-step - max lookback window if no datapoints found at the given time. If omitted, is set to 5m
-```
+
+* `query` - [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html) expression.
+* `time` - optional timestamp when to evaluate the `query`. If `time` is skipped, then the current timestamp is used.
+  The `time` param can be specified in the following formats:
+  * [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) such as `2022-08-10T12:45:43.000Z`.
+  * [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds. It can contains fractional part for millisecond precision.
+  * [Relative duration](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations)
+    comparing to the current timestamp. For example, `-1h` means `one hour before the current time`.
+* `step` - optional max lookback window for searching for raw samples when executing the `query`.
+  If `step` is skipped, then it is set to `5m` (5 minutes) by default.
 
 To understand how instant queries work, let's begin with a data sample:
 
@@ -429,8 +479,8 @@ foo_bar 1.00 1652170500000 # 2022-05-10 10:15:00
 foo_bar 4.00 1652170560000 # 2022-05-10 10:16:00
 ```
 
-The data sample contains a list of samples for one time series with time intervals between samples from 1m to 3m. If we
-plot this data sample on the system of coordinates, it will have the following form:
+The data sample contains a list of samples for `foo_bar` time series with time intervals between samples from 1m to 3m. If we
+plot this data sample on the graph, it will have the following form:
 
 <p style="text-align: center">
     <a href="keyConcepts_data_samples.png" target="_blank">
@@ -467,7 +517,7 @@ curl "http://<victoria-metrics-addr>/api/v1/query?query=foo_bar&time=2022-05-10T
 
 In response, VictoriaMetrics returns a single sample-timestamp pair with a value of `3` for the series
 `foo_bar` at the given moment of time `2022-05-10 10:03`. But, if we take a look at the original data sample again,
-we'll see that there is no data point at `2022-05-10 10:03`. What happens here is if there is no data point at the
+we'll see that there is no a raw sample at `2022-05-10 10:03`. What happens here is if there is no a raw sample at the
 requested timestamp, VictoriaMetrics will try to locate the closest sample on the left to the requested timestamp:
 
 <p style="text-align: center">
@@ -492,14 +542,23 @@ the following scenarios:
 Range query executes the query expression at the given time range with the given step:
 
 ```
-GET | POST /api/v1/query_range
+GET | POST /api/v1/query_range?query=...&start=...&end=...&step=...
+```
 
 Params:
-query - MetricsQL expression, required
-start - beginning (rfc3339 | unix_timestamp) of the time rage, required
-end - end (rfc3339 | unix_timestamp) of the time range. If omitted, current timestamp is used 
-step - step in seconds for evaluating query expression on the time range. If omitted, is set to 5m
-```
+* `query` - [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html) expression.
+* `start` - the starting timestamp of the time range for `query` evaluation.
+  The `start` param can be specified in the following formats:
+  * [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) such as `2022-08-10T12:45:43.000Z`.
+  * [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds. It can contains fractional part for millisecond precision.
+  * [Relative duration](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations)
+    comparing to the current timestamp. For example, `-1h` means `one hour before the current time`.
+* `end` - the ending timestamp of the time range for `query` evaluation.
+  If the `end` isn't set, then the `end` is automatically set to the current time.
+* `step` - the [interval](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations) between datapoints,
+  which must be returned from the range query.
+  The `query` is executed at `start`, `start+step`, `start+2*step`, ..., `end` timestamps.
+  If the `step` isn't set, then it is automatically set to `5m` (5 minutes).
 
 To get the values of `foo_bar` on time range from `2022-05-10 09:59:00` to `2022-05-10 10:17:00`, in VictoriaMetrics we
 need to issue a range query:
@@ -596,8 +655,8 @@ curl "http://<victoria-metrics-addr>/api/v1/query_range?query=foo_bar&step=1m&st
 
 In response, VictoriaMetrics returns `17` sample-timestamp pairs for the series `foo_bar` at the given time range
 from  `2022-05-10 09:59:00` to `2022-05-10 10:17:00`. But, if we take a look at the original data sample again, we'll
-see that it contains only 13 data points. What happens here is that the range query is actually
-an [instant query](#instant-query) executed `(start-end)/step` times on the time range from `start` to `end`. If we plot
+see that it contains only 13 raw samples. What happens here is that the range query is actually
+an [instant query](#instant-query) executed `1 + (start-end)/step` times on the time range from `start` to `end`. If we plot
 this request in VictoriaMetrics the graph will be shown as the following:
 
 <p style="text-align: center">
@@ -606,26 +665,24 @@ this request in VictoriaMetrics the graph will be shown as the following:
     </a>
 </p>
 
-
 The blue dotted lines on the pic are the moments when instant query was executed. Since instant query retains the
 ability to locate the missing point, the graph contains two types of points: `real` and `ephemeral` data
-points. `ephemeral` data point always repeats the left closest
-`real` data point (see red arrow on the pic above).
+points. `ephemeral` data point always repeats the left closest raw sample (see red arrow on the pic above).
 
-This behavior of adding ephemeral data points comes from the specifics of the [Pull model](#pull-model):
+This behavior of adding ephemeral data points comes from the specifics of the [pull model](#pull-model):
 
-* Metrics are scraped at fixed intervals;
-* Scrape may be skipped if the monitoring system is overloaded;
+* Metrics are scraped at fixed intervals.
+* Scrape may be skipped if the monitoring system is overloaded.
 * Scrape may fail due to network issues.
 
-According to these specifics, the range query assumes that if there is a missing data point then it is likely a missed
-scrape, so it fills it with the previous data point. The same will work for cases when `step` is lower than the actual
+According to these specifics, the range query assumes that if there is a missing raw sample then it is likely a missed
+scrape, so it fills it with the previous raw sample. The same will work for cases when `step` is lower than the actual
 interval between samples. In fact, if we set `step=1s` for the same request, we'll get about 1 thousand data points in
 response, where most of them are `ephemeral`.
 
 Sometimes, the lookbehind window for locating the datapoint isn't big enough and the graph will contain a gap. For range
 queries, lookbehind window isn't equal to the `step` parameter. It is calculated as the median of the intervals between
-the first 20 data points in the requested time range. In this way, VictoriaMetrics automatically adjusts the lookbehind
+the first 20 raw samples in the requested time range. In this way, VictoriaMetrics automatically adjusts the lookbehind
 window to fill gaps and detect stale series at the same time.
 
 Range queries are mostly used for plotting time series data over specified time ranges. These queries are extremely
@@ -635,36 +692,35 @@ useful in the following scenarios:
 * Correlate changes between multiple metrics on the time interval;
 * Observe trends and dynamics of the metric change.
 
-### MetricsQL
+If you need exporting raw samples from VictoriaMetrics, then take a look at [export APIs](https://docs.victoriametrics.com/#how-to-export-time-series).
 
-VictoriaMetrics provide a special query language for executing read queries
+### MetricsQL
 
-- [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html). MetricsQL is
-  a [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics) -like query language with a powerful set of
-  functions and features for working specifically with time series data. MetricsQL is backwards-compatible with PromQL,
-  so it shares most of the query concepts. For example, the basics concepts of PromQL are
-  described [here](https://valyala.medium.com/promql-tutorial-for-beginners-9ab455142085)
-  are applicable to MetricsQL as well.
+VictoriaMetrics provide a special query language for executing read queries - [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html).
+It is a [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics)-like query language with a powerful set of
+functions and features for working specifically with time series data. MetricsQL is backwards-compatible with PromQL,
+so it shares most of the query concepts. The basics concepts for PromQL and MetricsQL are
+described [here](https://valyala.medium.com/promql-tutorial-for-beginners-9ab455142085).
 
 #### Filtering
 
 In sections [instant query](#instant-query) and [range query](#range-query) we've already used MetricsQL to get data for
 metric `foo_bar`. It is as simple as just writing a metric name in the query:
 
-```MetricsQL
+```metricsql
 foo_bar
 ```
 
 A single metric name may correspond to multiple time series with distinct label sets. For example:
 
-```MetricsQL
+```metricsql
 requests_total{path="/", code="200"} 
 requests_total{path="/", code="403"} 
 ```
 
 To select only time series with specific label value specify the matching condition in curly braces:
 
-```MetricsQL
+```metricsql
 requests_total{code="200"} 
 ```
 
@@ -672,13 +728,13 @@ The query above will return all time series with the name `requests_total` and `
 match a label value. For negative match use `!=` operator. Filters also support regex matching `=~` for positive
 and `!~` for negative matching:
 
-```MetricsQL
+```metricsql
 requests_total{code=~"2.*"}
 ```
 
 Filters can also be combined:
 
-```MetricsQL
+```metricsql
 requests_total{code=~"200|204", path="/home"}
 ```
 
@@ -691,7 +747,7 @@ Sometimes it is required to return all the time series for multiple metric names
 the [data model section](#data-model), the metric name is just an ordinary label with a special name — `__name__`. So
 filtering by multiple metric names may be performed by applying regexps on metric names:
 
-```MetricsQL
+```metricsql
 {__name__=~"requests_(error|success)_total"}
 ```
 
@@ -701,17 +757,17 @@ The query above is supposed to return series for two metrics: `requests_error_to
 
 MetricsQL supports all the basic arithmetic operations:
 
-* addition (+)
-* subtraction (-)
-* multiplication (*)
-* division (/)
-* modulo (%)
-* power (^)
+* addition - `+`
+* subtraction - `-`
+* multiplication - `*`
+* division - `/`
+* modulo - `%`
+* power - `^`
 
-This allows performing various calculations. For example, the following query will calculate the percentage of error
-requests:
+This allows performing various calculations across multiple metrics.
+For example, the following query calculates the percentage of error requests:
 
-```MetricsQL
+```metricsql
 (requests_error_total / (requests_error_total + requests_success_total)) * 100
 ```
 
@@ -725,87 +781,89 @@ query may break or may lead to incorrect results. The basics of the matching rul
 * For each time series on the left side MetricsQL engine searches for the corresponding time series on the right side
   with the same set of labels, applies the operation for each data point and returns the resulting time series with the
   same set of labels. If there are no matches, then the time series is dropped from the result.
-* The matching rules may be augmented with ignoring, on, group_left and group_right modifiers.
-
-This could be complex, but in the majority of cases isn’t needed.
+* The matching rules may be augmented with `ignoring`, `on`, `group_left` and `group_right` modifiers.
+  See [these docs](https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching) for details.
 
 #### Comparison operations
 
 MetricsQL supports the following comparison operators:
 
-* equal (==)
-* not equal (!=)
-* greater (>)
-* greater-or-equal (>=)
-* less (<)
-* less-or-equal (<=)
+* equal - `==`
+* not equal - `!=`
+* greater - `>`
+* greater-or-equal - `>=`
+* less - `<`
+* less-or-equal - `<=`
 
 These operators may be applied to arbitrary MetricsQL expressions as with arithmetic operators. The result of the
 comparison operation is time series with only matching data points. For instance, the following query would return
-series only for processes where memory usage is > 100MB:
+series only for processes where memory usage exceeds `100MB`:
 
-```MetricsQL
+```metricsql
 process_resident_memory_bytes > 100*1024*1024
 ```
 
 #### Aggregation and grouping functions
 
 MetricsQL allows aggregating and grouping time series. Time series are grouped by the given set of labels and then the
-given aggregation function is applied for each group. For instance, the following query would return memory used by
-various processes grouped by instances (for the case when multiple processes run on the same instance):
+given aggregation function is applied individually per each group. For instance, the following query returns
+summary memory usage for each `job`:
 
-```MetricsQL
-sum(process_resident_memory_bytes) by (instance)
+```metricsql
+sum(process_resident_memory_bytes) by (job)
 ```
 
+See [docs for aggregate functions in MetricsQL](https://docs.victoriametrics.com/MetricsQL.html#aggregate-functions).
+
 #### Calculating rates
 
 One of the most widely used functions for [counters](#counter)
-is [rate](https://docs.victoriametrics.com/MetricsQL.html#rate). It calculates per-second rate for all the matching time
-series. For example, the following query will show how many bytes are received by the network per second:
+is [rate](https://docs.victoriametrics.com/MetricsQL.html#rate). It calculates the average per-second increase rate individually
+per each matching time series. For example, the following query shows the average per-second data receive speed
+per each monitored `node_exporter` instance, which exposes the `node_network_receive_bytes_total` metric:
 
-```MetricsQL
+```metricsql
 rate(node_network_receive_bytes_total)
 ```
 
-To calculate the rate, the query engine will need at least two data points to compare. Simplified rate calculation for
-each point looks like `(Vcurr-Vprev)/(Tcurr-Tprev)`, where `Vcurr` is the value at the current point — `Tcurr`, `Vprev`
-is the value at the point `Tprev=Tcurr-step`. The range between `Tcurr-Tprev` is usually equal to `step` parameter.
-If `step` value is lower than the real interval between data points, then it is ignored and a minimum real interval is
-used.
+By default VictoriaMetrics calculates the `rate` over [raw samples](#raw-samples) on the lookbehind window specified in the `step` param
+passed either to [instant query](#instant-query) or to [range query](#range-query).
+The interval on which `rate` needs to be calculated can be specified explicitly
+as [duration](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations) in square brackets:
 
-The interval on which `rate` needs to be calculated can be specified explicitly as `duration` in square brackets:
-
-```MetricsQL
+```metricsql
  rate(node_network_receive_bytes_total[5m])
 ```
 
-For this query the time duration to look back when calculating per-second rate for each point on the graph will be equal
-to `5m`.
+In this case VictoriaMetrics uses the specified lookbehind window - `5m` (5 minutes) - for calculating the average per-second increase rate.
+Bigger lookbehind windows usually lead to smoother graphs.
+
+`rate` strips metric name while leaving all the labels for the inner time series. If you need keeping the metric name,
+then add [keep_metric_names](https://docs.victoriametrics.com/MetricsQL.html#keep_metric_names) modifier
+after the `rate(..)`. For example, the following query leaves metric names after calculating the `rate()`:
 
-`rate` strips metric name while leaving all the labels for the inner time series. Do not apply `rate` to time series
-which may go up and down, such as [gauges](#gauge).
-`rate` must be applied only to [counters](#counter), which always go up. Even if counter gets reset (for instance, on
-service restart), `rate` knows how to deal with it.
+```metricsql
+rate(node_network_receive_bytes_total) keep_metric_names
+```
+
+`rate()` must be apllied only to [counters](#counter). The result of applying the `rate()` to [gauge](#gauge) is undefined.
 
 ### Visualizing time series
 
-VictoriaMetrics has a built-in graphical User Interface for querying and visualizing metrics
+VictoriaMetrics has a built-in graphical User Interface for querying and visualizing metrics -
 [VMUI](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#vmui).
 Open `http://victoriametrics:8428/vmui` page, type the query and see the results:
 
 {% include img.html href="keyConcepts_vmui.png" %}
 
-VictoriaMetrics supports [Prometheus HTTP API](https://prometheus.io/docs/prometheus/latest/querying/api/)
-which makes it possible
-to [use with Grafana](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#grafana-setup). Play more with
-Grafana integration in VictoriaMetrics
-sandbox [https://play-grafana.victoriametrics.com](https://play-grafana.victoriametrics.com).
+VictoriaMetrics supports [Prometheus HTTP API](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#prometheus-querying-api-usage)
+which makes it possible to [query it with Grafana](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#grafana-setup)
+in the same way as Grafana queries Prometheus.
 
 ## Modify data
 
 VictoriaMetrics stores time series data in [MergeTree](https://en.wikipedia.org/wiki/Log-structured_merge-tree)-like
-data structures. While this approach if very efficient for write-heavy databases, it applies some limitations on data
+data structures. While this approach is very efficient for write-heavy databases, it applies some limitations on data
 updates. In short, modifying already written [time series](#time-series) requires re-writing the whole data block where
 it is stored. Due to this limitation, VictoriaMetrics does not support direct data modification.
 
@@ -822,5 +880,9 @@ details [here](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.ht
 
 ### Deduplication
 
-VictoriaMetrics supports data points deduplication after data was written to the storage. See more
-details [here](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#deduplication).
+VictoriaMetrics supports data deduplication. See [these docs](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#deduplication).
+
+
+### Downsampling
+
+VictoriaMetrics supports data downsampling - see [these docs](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#downsampling).
diff --git a/docs/vmagent.md b/docs/vmagent.md
index 510a1a99e..ad20d4cd2 100644
--- a/docs/vmagent.md
+++ b/docs/vmagent.md
@@ -182,7 +182,7 @@ See [the list of supported service discovery types for Prometheus scrape targets
 
 ## scrape_config enhancements
 
-`vmagent` supports the following additional options in `scrape_configs` section:
+`vmagent` supports the following additional options in [scrape_configs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs) section:
 
 * `headers` - a list of HTTP headers to send to scrape target with each scrape request. This can be used when the scrape target needs custom authorization and authentication. For example:
 
@@ -203,9 +203,12 @@ scrape_configs:
 * `relabel_debug: true` for enabling debug logging during relabeling of the discovered targets. See [these docs](#relabeling).
 * `metric_relabel_debug: true` for enabling debug logging during relabeling of the scraped metrics. See [these docs](#relabeling).
 
+See [scrape_configs docs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs) for more details on all the supported options.
+
+
 ## Loading scrape configs from multiple files
 
-`vmagent` supports loading scrape configs from multiple files specified in the `scrape_config_files` section of `-promscrape.config` file. For example, the following `-promscrape.config` instructs `vmagent` loading scrape configs from all the `*.yml` files under `configs` directory, from `single_scrape_config.yml` local file and from `https://config-server/scrape_config.yml` url:
+`vmagent` supports loading [scrape configs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs) from multiple files specified in the `scrape_config_files` section of `-promscrape.config` file. For example, the following `-promscrape.config` instructs `vmagent` loading scrape configs from all the `*.yml` files under `configs` directory, from `single_scrape_config.yml` local file and from `https://config-server/scrape_config.yml` url:
 
 ```yml
 scrape_config_files:
@@ -214,7 +217,7 @@ scrape_config_files:
 - https://config-server/scrape_config.yml
 ```
 
-Every referred file can contain arbitrary number of [supported scrape configs](#how-to-collect-metrics-in-prometheus-format). There is no need in specifying top-level `scrape_configs` section in these files. For example:
+Every referred file can contain arbitrary number of [supported scrape configs](https://docs.victoriametrics.com/sd_configs.html#scrape_configs). There is no need in specifying top-level `scrape_configs` section in these files. For example:
 
 ```yml
 - job_name: foo
@@ -342,85 +345,94 @@ The following articles contain useful information about Prometheus relabeling:
 
 ## Relabeling enhancements
 
-VictoriaMetrics provides the following additional relabeling actions on top of standard actions from the [Prometheus relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config):
-
-* `replace_all` replaces all of the occurrences of `regex` in the values of `source_labels` with the `replacement` and stores the results in the `target_label`. For example, the following relabeling config replaces all the occurrences of `-` char in metric names with `_` char (e.g. `foo-bar-baz` metric name is transformed into `foo_bar_baz`):
+* The `replacement` option can refer arbitrary labels via {% raw %}`{{label_name}}`{% endraw %} placeholders. Such placeholders are substituted with the corresponding label value. For example, the following relabeling rule sets `instance-job` label value to `host123-foo` when applied to the metric with `{instance="host123",job="foo"}` labels:
 
+  {% raw %}
   ```yaml
-  - action: replace_all
-    source_labels: ["__name__"]
-    target_label: "__name__"
-    regex: "-"
-    replacement: "_"
+  - target_label: "instance-job"
+    replacement: "{{instance}}-{{job}}"
   ```
+  {% endraw %}
 
-* `labelmap_all` replaces all of the occurrences of `regex` in all the label names with the `replacement`. For example, the following relabeling config replaces all the occurrences of `-` char in all the label names with `_` char (e.g. `foo-bar-baz` label name is transformed into `foo_bar_baz`):
+* An optional `if` filter can be used for conditional relabeling. The `if` filter may contain arbitrary [time series selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). For example, the following relabeling rule drops metrics, which don't match `foo{bar="baz"}` series selector, while leaving the rest of metrics:
 
   ```yaml
-  - action: labelmap_all
-    regex: "-"
-    replacement: "_"
+  - action: keep
+    if: 'foo{bar="baz"}'
   ```
 
-* `keep_if_equal`: keeps the entry if all the label values from `source_labels` are equal, while dropping all the other entries. For example, the following relabeling config keeps targets if they contain equal values for `instance` and `host` labels, while dropping all the other targets:
+  This is equivalent to less clear Prometheus-compatible relabeling rule:
 
   ```yaml
-  - action: keep_if_equal
-    source_labels: ["instance", "host"]
+  - action: keep
+    source_labels: [__name__, bar]
+    regex: 'foo;baz'
   ```
 
-* `drop_if_equal`: drops the entry if all the label values from `source_labels` are equal, while keeping all the other entries. For example, the following relabeling config drops targets if they contain equal values for `instance` and `host` labels, while keeping all the other targets:
+* The `regex` value can be split into multiple lines for improved readability and maintainability. These lines are automatically joined with `|` char when parsed. For example, the following configs are equivalent:
 
   ```yaml
-  - action: drop_if_equal
-    source_labels: ["instance", "host"]
+  - action: keep_metrics
+    regex: "metric_a|metric_b|foo_.+"
   ```
 
-* `keep_metrics`: keeps all the metrics with names matching the given `regex`, while dropping all the other metrics. For example, the following relabeling config keeps metrics with `fo` and `bar` names, while dropping all the other metrics:
-
   ```yaml
   - action: keep_metrics
-    regex: "foo|bar"
+    regex:
+    - "metric_a"
+    - "metric_b"
+    - "foo_.+"
   ```
 
-* `drop_metrics`: drops all the metrics with names matching the given `regex`, while keeping all the other metrics. For example, the following relabeling config drops metrics with `foo` and `bar` names, while leaving all the other metrics:
+* VictoriaMetrics provides the following additional relabeling actions on top of standard actions from the [Prometheus relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config):
 
-  ```yaml
-  - action: drop_metrics
-    regex: "foo|bar"
-  ```
+  * `replace_all` replaces all of the occurrences of `regex` in the values of `source_labels` with the `replacement` and stores the results in the `target_label`. For example, the following relabeling config replaces all the occurrences of `-` char in metric names with `_` char (e.g. `foo-bar-baz` metric name is transformed into `foo_bar_baz`):
 
-* `graphite`: applies Graphite-style relabeling to metric name. See [these docs](#graphite-relabeling) for details.
+    ```yaml
+    - action: replace_all
+      source_labels: ["__name__"]
+      target_label: "__name__"
+      regex: "-"
+      replacement: "_"
+    ```
 
-The `regex` value can be split into multiple lines for improved readability and maintainability. These lines are automatically joined with `|` char when parsed. For example, the following configs are equivalent:
+  * `labelmap_all` replaces all of the occurrences of `regex` in all the label names with the `replacement`. For example, the following relabeling config replaces all the occurrences of `-` char in all the label names with `_` char (e.g. `foo-bar-baz` label name is transformed into `foo_bar_baz`):
 
-```yaml
-- action: keep_metrics
-  regex: "metric_a|metric_b|foo_.+"
-```
+    ```yaml
+    - action: labelmap_all
+      regex: "-"
+      replacement: "_"
+    ```
 
-```yaml
-- action: keep_metrics
-  regex:
-  - "metric_a"
-  - "metric_b"
-  - "foo_.+"
-```
+  * `keep_if_equal`: keeps the entry if all the label values from `source_labels` are equal, while dropping all the other entries. For example, the following relabeling config keeps targets if they contain equal values for `instance` and `host` labels, while dropping all the other targets:
 
-VictoriaMetrics components support an optional `if` filter in relabeling configs, which can be used for conditional relabeling. The `if` filter may contain arbitrary [time series selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). For example, the following relabeling rule drops metrics, which don't match `foo{bar="baz"}` series selector, while leaving the rest of metrics:
+    ```yaml
+    - action: keep_if_equal
+      source_labels: ["instance", "host"]
+    ```
 
-```yaml
-- action: keep
-  if: 'foo{bar="baz"}'
-```
+  * `drop_if_equal`: drops the entry if all the label values from `source_labels` are equal, while keeping all the other entries. For example, the following relabeling config drops targets if they contain equal values for `instance` and `host` labels, while keeping all the other targets:
 
-This is equivalent to less clear Prometheus-compatible relabeling rule:
+    ```yaml
+    - action: drop_if_equal
+      source_labels: ["instance", "host"]
+    ```
 
-```yaml
-- action: keep
-  source_labels: [__name__, bar]
-  regex: 'foo;baz'
-```
+  * `keep_metrics`: keeps all the metrics with names matching the given `regex`, while dropping all the other metrics. For example, the following relabeling config keeps metrics with `fo` and `bar` names, while dropping all the other metrics:
+
+    ```yaml
+    - action: keep_metrics
+      regex: "foo|bar"
+    ```
+
+  * `drop_metrics`: drops all the metrics with names matching the given `regex`, while keeping all the other metrics. For example, the following relabeling config drops metrics with `foo` and `bar` names, while leaving all the other metrics:
+
+    ```yaml
+    - action: drop_metrics
+      regex: "foo|bar"
+    ```
+
+  * `graphite`: applies Graphite-style relabeling to metric name. See [these docs](#graphite-relabeling) for details.
 
 ## Graphite relabeling
 
diff --git a/go.mod b/go.mod
index fe34e99e9..7df5bb7a5 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/VictoriaMetrics/fasthttp v1.1.0
 	github.com/VictoriaMetrics/metrics v1.22.2
 	github.com/VictoriaMetrics/metricsql v0.44.1
-	github.com/aws/aws-sdk-go v1.44.76
+	github.com/aws/aws-sdk-go v1.44.81
 	github.com/cespare/xxhash/v2 v2.1.2
 
 	// TODO: switch back to https://github.com/cheggaaa/pb/v3 when v3-pooling branch
@@ -30,14 +30,14 @@ require (
 	github.com/valyala/quicktemplate v1.7.0
 	golang.org/x/net v0.0.0-20220812174116-3211cb980234
 	golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7
-	golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
-	google.golang.org/api v0.92.0
+	golang.org/x/sys v0.0.0-20220818161305-2296e01440c6
+	google.golang.org/api v0.93.0
 	gopkg.in/yaml.v2 v2.4.0
 )
 
 require (
 	cloud.google.com/go v0.103.0 // indirect
-	cloud.google.com/go/compute v1.8.0 // indirect
+	cloud.google.com/go/compute v1.9.0 // indirect
 	cloud.google.com/go/iam v0.3.0 // indirect
 	github.com/VividCortex/ewma v1.2.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
@@ -53,8 +53,8 @@ require (
 	github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
 	github.com/googleapis/gax-go/v2 v2.5.1 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
-	github.com/mattn/go-colorable v0.1.12 // indirect
-	github.com/mattn/go-isatty v0.0.14 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-isatty v0.0.16 // indirect
 	github.com/mattn/go-runewidth v0.0.13 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
 	github.com/oklog/ulid v1.3.1 // indirect
@@ -71,11 +71,11 @@ require (
 	go.opencensus.io v0.23.0 // indirect
 	go.uber.org/atomic v1.10.0 // indirect
 	go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 // indirect
-	golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
+	golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
 	golang.org/x/text v0.3.7 // indirect
 	golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20220812140447-cec7f5303424 // indirect
+	google.golang.org/genproto v0.0.0-20220819174105-e9f053255caa // indirect
 	google.golang.org/grpc v1.48.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 )
diff --git a/go.sum b/go.sum
index ca4816a69..a8ab4198d 100644
--- a/go.sum
+++ b/go.sum
@@ -46,8 +46,8 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m
 cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
 cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
 cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
-cloud.google.com/go/compute v1.8.0 h1:NLtR56/eKx9K1s2Tw/4hec2vsU1S3WeKRMj8HXbBo6E=
-cloud.google.com/go/compute v1.8.0/go.mod h1:boQ44qJsMqZjKzzsEkoJWQGj4h8ygmyk17UArClWzmg=
+cloud.google.com/go/compute v1.9.0 h1:ED/FP4xv8GJw63v556/ASNc1CeeLUO2Bs8nzaHchkHg=
+cloud.google.com/go/compute v1.9.0/go.mod h1:lWv1h/zUWTm/LozzfTJhBSkd6ShQq8la8VeeuOEGxfY=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc=
@@ -149,8 +149,8 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
 github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
 github.com/aws/aws-sdk-go v1.35.31/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
-github.com/aws/aws-sdk-go v1.44.76 h1:5e8yGO/XeNYKckOjpBKUd5wStf0So3CrQIiOMCVLpOI=
-github.com/aws/aws-sdk-go v1.44.76/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
+github.com/aws/aws-sdk-go v1.44.81 h1:C8oBZ+a+ka0qk3Q24MohQIFq0tkbO8IAu5tfpAMKVWE=
+github.com/aws/aws-sdk-go v1.44.81/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -612,16 +612,17 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
-github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
@@ -1045,8 +1046,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
+golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1126,7 +1127,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1143,8 +1143,9 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U=
+golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1292,8 +1293,8 @@ google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3
 google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
 google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
 google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
-google.golang.org/api v0.92.0 h1:8JHk7q/+rJla+iRsWj9FQ9/wjv2M1SKtpKSdmLhxPT0=
-google.golang.org/api v0.92.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
+google.golang.org/api v0.93.0 h1:T2xt9gi0gHdxdnRkVQhT8mIvPaXKNsDNWz+L696M66M=
+google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1387,8 +1388,8 @@ google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljW
 google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
 google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
 google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220812140447-cec7f5303424 h1:zZnTt15U44/Txe/9cN/tVbteBkPMiyXK48hPsKRmqj4=
-google.golang.org/genproto v0.0.0-20220812140447-cec7f5303424/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220819174105-e9f053255caa h1:Ux9yJCyf598uEniFPSyp8g1jtGTt77m+lzYyVgrWQaQ=
+google.golang.org/genproto v0.0.0-20220819174105-e9f053255caa/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
diff --git a/lib/promrelabel/config.go b/lib/promrelabel/config.go
index 830cf7cfe..bd31e99b1 100644
--- a/lib/promrelabel/config.go
+++ b/lib/promrelabel/config.go
@@ -343,8 +343,10 @@ func parseRelabelConfig(rc *RelabelConfig) (*parsedRelabelConfig, error) {
 		graphiteMatchTemplate: graphiteMatchTemplate,
 		graphiteLabelRules:    graphiteLabelRules,
 
-		regexOriginal:                regexOriginalCompiled,
-		hasCaptureGroupInTargetLabel: strings.Contains(targetLabel, "$"),
-		hasCaptureGroupInReplacement: strings.Contains(replacement, "$"),
+		regexOriginal: regexOriginalCompiled,
+
+		hasCaptureGroupInTargetLabel:   strings.Contains(targetLabel, "$"),
+		hasCaptureGroupInReplacement:   strings.Contains(replacement, "$"),
+		hasLabelReferenceInReplacement: strings.Contains(replacement, "{{"),
 	}, nil
 }
diff --git a/lib/promrelabel/relabel.go b/lib/promrelabel/relabel.go
index 9c0516639..1d6a92622 100644
--- a/lib/promrelabel/relabel.go
+++ b/lib/promrelabel/relabel.go
@@ -28,9 +28,11 @@ type parsedRelabelConfig struct {
 	graphiteMatchTemplate *graphiteMatchTemplate
 	graphiteLabelRules    []graphiteLabelRule
 
-	regexOriginal                *regexp.Regexp
-	hasCaptureGroupInTargetLabel bool
-	hasCaptureGroupInReplacement bool
+	regexOriginal *regexp.Regexp
+
+	hasCaptureGroupInTargetLabel   bool
+	hasCaptureGroupInReplacement   bool
+	hasLabelReferenceInReplacement bool
 }
 
 // String returns human-readable representation for prc.
@@ -172,10 +174,16 @@ func (prc *parsedRelabelConfig) apply(labels []prompbmarshal.Label, labelsOffset
 		return labels
 	case "replace":
 		// Store `replacement` at `target_label` if the `regex` matches `source_labels` joined with `separator`
+		replacement := prc.Replacement
 		bb := relabelBufPool.Get()
+		if prc.hasLabelReferenceInReplacement {
+			// Fill {{labelName}} references in the replacement
+			bb.B = fillLabelReferences(bb.B[:0], replacement, labels[labelsOffset:])
+			replacement = string(bb.B)
+		}
 		bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
 		if prc.Regex == defaultRegexForRelabelConfig && !prc.hasCaptureGroupInTargetLabel {
-			if prc.Replacement == "$1" {
+			if replacement == "$1" {
 				// Fast path for the rule that copies source label values to destination:
 				// - source_labels: [...]
 				//   target_label: foobar
@@ -188,7 +196,7 @@ func (prc *parsedRelabelConfig) apply(labels []prompbmarshal.Label, labelsOffset
 				// - target_label: foobar
 				//   replacement: something-here
 				relabelBufPool.Put(bb)
-				labels = setLabelValue(labels, labelsOffset, prc.TargetLabel, prc.Replacement)
+				labels = setLabelValue(labels, labelsOffset, prc.TargetLabel, replacement)
 				return labels
 			}
 		}
@@ -203,7 +211,7 @@ func (prc *parsedRelabelConfig) apply(labels []prompbmarshal.Label, labelsOffset
 		if prc.hasCaptureGroupInTargetLabel {
 			nameStr = prc.expandCaptureGroups(nameStr, sourceStr, match)
 		}
-		valueStr := prc.expandCaptureGroups(prc.Replacement, sourceStr, match)
+		valueStr := prc.expandCaptureGroups(replacement, sourceStr, match)
 		relabelBufPool.Put(bb)
 		return setLabelValue(labels, labelsOffset, nameStr, valueStr)
 	case "replace_all":
@@ -539,3 +547,25 @@ func labelsToString(labels []prompbmarshal.Label) string {
 	b = append(b, '}')
 	return string(b)
 }
+
+func fillLabelReferences(dst []byte, replacement string, labels []prompbmarshal.Label) []byte {
+	s := replacement
+	for len(s) > 0 {
+		n := strings.Index(s, "{{")
+		if n < 0 {
+			return append(dst, s...)
+		}
+		dst = append(dst, s[:n]...)
+		s = s[n+2:]
+		n = strings.Index(s, "}}")
+		if n < 0 {
+			dst = append(dst, "{{"...)
+			return append(dst, s...)
+		}
+		labelName := s[:n]
+		s = s[n+2:]
+		labelValue := GetLabelValueByName(labels, labelName)
+		dst = append(dst, labelValue...)
+	}
+	return dst
+}
diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go
index 1405d0967..50538b1d3 100644
--- a/vendor/cloud.google.com/go/compute/metadata/metadata.go
+++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go
@@ -71,6 +71,7 @@ func newDefaultHTTPClient() *http.Client {
 				KeepAlive: 30 * time.Second,
 			}).Dial,
 		},
+		Timeout: 5 * time.Second,
 	}
 }
 
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
index 65f81eeba..ed81d7107 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
@@ -3928,6 +3928,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-southeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-3",
+				}: endpoint{},
 				endpointKey{
 					Region: "ca-central-1",
 				}: endpoint{},
@@ -18269,6 +18272,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-southeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-3",
+				}: endpoint{},
 				endpointKey{
 					Region: "ca-central-1",
 				}: endpoint{},
@@ -24465,9 +24471,18 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-southeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ca-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "eu-west-1",
 				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-2",
+				}: endpoint{},
 				endpointKey{
 					Region: "us-east-1",
 				}: endpoint{},
@@ -31270,6 +31285,16 @@ var awsusgovPartition = partition{
 				},
 			},
 		},
+		"wellarchitected": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "us-gov-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-gov-west-1",
+				}: endpoint{},
+			},
+		},
 		"workspaces": service{
 			Endpoints: serviceEndpoints{
 				endpointKey{
@@ -31420,6 +31445,9 @@ var awsisoPartition = partition{
 		},
 		"appconfigdata": service{
 			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "us-iso-east-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "us-iso-west-1",
 				}: endpoint{},
@@ -32175,6 +32203,13 @@ var awsisobPartition = partition{
 				}: endpoint{},
 			},
 		},
+		"appconfigdata": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "us-isob-east-1",
+				}: endpoint{},
+			},
+		},
 		"application-autoscaling": service{
 			Defaults: endpointDefaults{
 				defaultKey{}: endpoint{
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go
index e4d6ce676..c15045b52 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/version.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go
@@ -5,4 +5,4 @@ package aws
 const SDKName = "aws-sdk-go"
 
 // SDKVersion is the version of this SDK
-const SDKVersion = "1.44.76"
+const SDKVersion = "1.44.81"
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
index 831b0110c..2c0cbba90 100644
--- a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
@@ -3,6 +3,7 @@ package query
 import (
 	"encoding/xml"
 	"fmt"
+	"strings"
 
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/request"
@@ -62,7 +63,7 @@ func UnmarshalError(r *request.Request) {
 	}
 
 	r.Error = awserr.NewRequestFailure(
-		awserr.New(respErr.Code, respErr.Message, nil),
+		awserr.New(strings.TrimSpace(respErr.Code), strings.TrimSpace(respErr.Message), nil),
 		r.HTTPResponse.StatusCode,
 		reqID,
 	)
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go
index 5e2cd8242..ebcc9b405 100644
--- a/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go
+++ b/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go
@@ -12,7 +12,7 @@
 // API namespaces will continue to retain their original name for backward compatibility
 // purposes. For more information, see Amazon Web Services SSO rename (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed).
 //
-// This API reference guide describes the Amazon Web Services SSO Portal operations
+// This reference guide describes the Amazon Web Services SSO Portal operations
 // that you can call programatically and includes detailed information on data
 // types and errors.
 //
diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go
index 4c0850a45..cbee7a4e2 100644
--- a/vendor/golang.org/x/sync/errgroup/errgroup.go
+++ b/vendor/golang.org/x/sync/errgroup/errgroup.go
@@ -61,8 +61,8 @@ func (g *Group) Wait() error {
 // It blocks until the new goroutine can be added without the number of
 // active goroutines in the group exceeding the configured limit.
 //
-// The first call to return a non-nil error cancels the group; its error will be
-// returned by Wait.
+// The first call to return a non-nil error cancels the group's context, if the
+// group was created by calling WithContext. The error will be returned by Wait.
 func (g *Group) Go(f func() error) {
 	if g.sem != nil {
 		g.sem <- token{}
diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh
index 6fc18353d..3b2335d5f 100644
--- a/vendor/golang.org/x/sys/unix/mkall.sh
+++ b/vendor/golang.org/x/sys/unix/mkall.sh
@@ -156,10 +156,10 @@ openbsd_amd64)
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 openbsd_arm)
+	mkasm="go run mkasm.go"
 	mkerrors="$mkerrors"
-	mksyscall="go run mksyscall.go -l32 -openbsd -arm"
+	mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
 	mksysctl="go run mksysctl_openbsd.go"
-	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 	# Let the type of C char be signed for making the bare syscall
 	# API consistent across platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
index e23c33de6..5930a8972 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (openbsd && 386) || (openbsd && amd64) || (openbsd && arm64)
-// +build openbsd,386 openbsd,amd64 openbsd,arm64
+//go:build (openbsd && 386) || (openbsd && amd64) || (openbsd && arm) || (openbsd && arm64)
+// +build openbsd,386 openbsd,amd64 openbsd,arm openbsd,arm64
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
index 69f803006..8da6791d1 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -l32 -openbsd -arm -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
+// go run mksyscall.go -l32 -openbsd -arm -libc -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build openbsd && arm
@@ -16,7 +16,7 @@ var _ syscall.Errno
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -24,20 +24,28 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
 	return
 }
 
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -45,10 +53,14 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err
 	return
 }
 
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -56,30 +68,42 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
 	return
 }
 
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -87,66 +111,94 @@ func socket(domain int, typ int, proto int) (fd int, err error) {
 	return
 }
 
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -156,7 +208,7 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -164,6 +216,10 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl
 	return
 }
 
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -173,17 +229,21 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -191,10 +251,14 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
 	return
 }
 
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -202,10 +266,14 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
 	return
 }
 
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -213,6 +281,10 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne
 	return
 }
 
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func utimes(path string, timeval *[2]Timeval) (err error) {
@@ -221,27 +293,35 @@ func utimes(path string, timeval *[2]Timeval) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -249,6 +329,10 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
 	return
 }
 
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Madvise(b []byte, behav int) (err error) {
@@ -258,13 +342,17 @@ func Madvise(b []byte, behav int) (err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlock(b []byte) (err error) {
@@ -274,23 +362,31 @@ func Mlock(b []byte) (err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mprotect(b []byte, prot int) (err error) {
@@ -300,13 +396,17 @@ func Mprotect(b []byte, prot int) (err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Msync(b []byte, flags int) (err error) {
@@ -316,13 +416,17 @@ func Msync(b []byte, flags int) (err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlock(b []byte) (err error) {
@@ -332,33 +436,45 @@ func Munlock(b []byte) (err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdents(fd int, buf []byte) (n int, err error) {
@@ -368,7 +484,7 @@ func Getdents(fd int, buf []byte) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,6 +492,10 @@ func Getdents(fd int, buf []byte) (n int, err error) {
 	return
 }
 
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getcwd(buf []byte) (n int, err error) {
@@ -385,7 +505,7 @@ func Getcwd(buf []byte) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -393,16 +513,24 @@ func Getcwd(buf []byte) (n int, err error) {
 	return
 }
 
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
@@ -412,17 +540,21 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -430,6 +562,10 @@ func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int,
 	return
 }
 
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -438,23 +574,31 @@ func Access(path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -463,13 +607,17 @@ func Chdir(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -478,13 +626,17 @@ func Chflags(path string, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -493,13 +645,17 @@ func Chmod(path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -508,13 +664,17 @@ func Chown(path string, uid int, gid int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -523,27 +683,35 @@ func Chroot(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -551,33 +719,49 @@ func Dup(fd int) (nfd int, err error) {
 	return
 }
 
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup3(from int, to int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -586,43 +770,59 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -631,23 +831,31 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
@@ -656,27 +864,35 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -684,16 +900,24 @@ func Fpathconf(fd int, name int) (val int, err error) {
 	return
 }
 
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
@@ -702,71 +926,99 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_ftruncate_trampoline_addr, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -774,34 +1026,50 @@ func Getpgid(pid int) (pgid int, err error) {
 	return
 }
 
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -809,20 +1077,28 @@ func Getpriority(which int, who int) (prio int, err error) {
 	return
 }
 
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrtable() (rtable int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
 	rtable = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -830,20 +1106,28 @@ func Getrtable() (rtable int, err error) {
 	return
 }
 
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -851,46 +1135,66 @@ func Getsid(pid int) (sid int, err error) {
 	return
 }
 
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum syscall.Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -898,6 +1202,10 @@ func Kqueue() (fd int, err error) {
 	return
 }
 
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -906,13 +1214,17 @@ func Lchown(path string, uid int, gid int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -926,13 +1238,17 @@ func Link(path string, link string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
@@ -946,23 +1262,31 @@ func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err er
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -971,13 +1295,17 @@ func Lstat(path string, stat *Stat_t) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -986,13 +1314,17 @@ func Mkdir(path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdirat(dirfd int, path string, mode uint32) (err error) {
@@ -1001,13 +1333,17 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -1016,13 +1352,17 @@ func Mkfifo(path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
@@ -1031,13 +1371,17 @@ func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -1046,13 +1390,17 @@ func Mknod(path string, mode uint32, dev int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
@@ -1061,23 +1409,31 @@ func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -1086,7 +1442,7 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1094,6 +1450,10 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
 	return
 }
 
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
@@ -1102,7 +1462,7 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1110,6 +1470,10 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
 	return
 }
 
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -1118,7 +1482,7 @@ func Pathconf(path string, name int) (val int, err error) {
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1126,6 +1490,10 @@ func Pathconf(path string, name int) (val int, err error) {
 	return
 }
 
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -1135,7 +1503,7 @@ func pread(fd int, p []byte, offset int64) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1143,6 +1511,10 @@ func pread(fd int, p []byte, offset int64) (n int, err error) {
 	return
 }
 
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -1152,7 +1524,7 @@ func pwrite(fd int, p []byte, offset int64) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1160,6 +1532,10 @@ func pwrite(fd int, p []byte, offset int64) (n int, err error) {
 	return
 }
 
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -1169,7 +1545,7 @@ func read(fd int, p []byte) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,6 +1553,10 @@ func read(fd int, p []byte) (n int, err error) {
 	return
 }
 
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -1191,7 +1571,7 @@ func Readlink(path string, buf []byte) (n int, err error) {
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,6 +1579,10 @@ func Readlink(path string, buf []byte) (n int, err error) {
 	return
 }
 
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
@@ -1213,7 +1597,7 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,6 +1605,10 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
 	return
 }
 
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -1234,13 +1622,17 @@ func Rename(from string, to string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Renameat(fromfd int, from string, tofd int, to string) (err error) {
@@ -1254,13 +1646,17 @@ func Renameat(fromfd int, from string, tofd int, to string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -1269,13 +1665,17 @@ func Revoke(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -1284,17 +1684,21 @@ func Rmdir(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	r0, r1, e1 := syscall_syscall6(libc_lseek_trampoline_addr, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
 	newoffset = int64(int64(r1)<<32 | int64(r0))
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1302,10 +1706,14 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
 	return
 }
 
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1313,36 +1721,52 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
 	return
 }
 
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1351,97 +1775,133 @@ func Setlogin(name string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrtable(rtable int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1449,26 +1909,38 @@ func Setsid() (pid int, err error) {
 	return
 }
 
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1477,13 +1949,17 @@ func Stat(path string, stat *Stat_t) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1492,13 +1968,17 @@ func Statfs(path string, stat *Statfs_t) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1512,13 +1992,17 @@ func Symlink(path string, link string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
@@ -1532,23 +2016,31 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1557,21 +2049,29 @@ func Truncate(path string, length int64) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1580,13 +2080,17 @@ func Unlink(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlinkat(dirfd int, path string, flags int) (err error) {
@@ -1595,13 +2099,17 @@ func Unlinkat(dirfd int, path string, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1610,13 +2118,17 @@ func Unmount(path string, flags int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1626,7 +2138,7 @@ func write(fd int, p []byte) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,10 +2146,14 @@ func write(fd int, p []byte) (n int, err error) {
 	return
 }
 
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	r0, _, e1 := syscall_syscall9(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1645,20 +2161,28 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (
 	return
 }
 
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1669,7 +2193,7 @@ func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1685,9 +2209,13 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
new file mode 100644
index 000000000..9ad116d9f
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd arm
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getgroups_trampoline_addr(SB)/4, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setgroups_trampoline_addr(SB)/4, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $4
+DATA	·libc_wait4_trampoline_addr(SB)/4, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $4
+DATA	·libc_accept_trampoline_addr(SB)/4, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $4
+DATA	·libc_bind_trampoline_addr(SB)/4, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $4
+DATA	·libc_connect_trampoline_addr(SB)/4, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $4
+DATA	·libc_socket_trampoline_addr(SB)/4, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsockopt_trampoline_addr(SB)/4, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setsockopt_trampoline_addr(SB)/4, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpeername_trampoline_addr(SB)/4, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsockname_trampoline_addr(SB)/4, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_shutdown_trampoline_addr(SB)/4, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $4
+DATA	·libc_socketpair_trampoline_addr(SB)/4, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $4
+DATA	·libc_recvfrom_trampoline_addr(SB)/4, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sendto_trampoline_addr(SB)/4, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $4
+DATA	·libc_recvmsg_trampoline_addr(SB)/4, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sendmsg_trampoline_addr(SB)/4, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kevent_trampoline_addr(SB)/4, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $4
+DATA	·libc_utimes_trampoline_addr(SB)/4, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $4
+DATA	·libc_futimes_trampoline_addr(SB)/4, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_poll(SB)
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $4
+DATA	·libc_poll_trampoline_addr(SB)/4, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_madvise(SB)
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $4
+DATA	·libc_madvise_trampoline_addr(SB)/4, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlock(SB)
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mlock_trampoline_addr(SB)/4, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlockall(SB)
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mlockall_trampoline_addr(SB)/4, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mprotect(SB)
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mprotect_trampoline_addr(SB)/4, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_msync_trampoline_addr(SB)/4, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlock(SB)
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munlock_trampoline_addr(SB)/4, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlockall(SB)
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munlockall_trampoline_addr(SB)/4, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pipe2_trampoline_addr(SB)/4, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getdents_trampoline_addr(SB)/4, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ioctl_trampoline_addr(SB)/4, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ppoll(SB)
+
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ppoll_trampoline_addr(SB)/4, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $4
+DATA	·libc_access_trampoline_addr(SB)/4, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $4
+DATA	·libc_adjtime_trampoline_addr(SB)/4, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chdir_trampoline_addr(SB)/4, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chflags_trampoline_addr(SB)/4, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chmod_trampoline_addr(SB)/4, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chown_trampoline_addr(SB)/4, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chroot_trampoline_addr(SB)/4, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $4
+DATA	·libc_close_trampoline_addr(SB)/4, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup_trampoline_addr(SB)/4, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup2_trampoline_addr(SB)/4, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup3(SB)
+
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup3_trampoline_addr(SB)/4, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_exit_trampoline_addr(SB)/4, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_faccessat(SB)
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_faccessat_trampoline_addr(SB)/4, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchdir_trampoline_addr(SB)/4, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchflags_trampoline_addr(SB)/4, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchmod_trampoline_addr(SB)/4, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmodat(SB)
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchmodat_trampoline_addr(SB)/4, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchown_trampoline_addr(SB)/4, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchownat(SB)
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchownat_trampoline_addr(SB)/4, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_flock_trampoline_addr(SB)/4, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fpathconf_trampoline_addr(SB)/4, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstat_trampoline_addr(SB)/4, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstatat_trampoline_addr(SB)/4, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstatfs_trampoline_addr(SB)/4, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fsync_trampoline_addr(SB)/4, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ftruncate_trampoline_addr(SB)/4, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getegid_trampoline_addr(SB)/4, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_geteuid_trampoline_addr(SB)/4, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getgid_trampoline_addr(SB)/4, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpgid_trampoline_addr(SB)/4, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpgrp_trampoline_addr(SB)/4, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpid_trampoline_addr(SB)/4, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getppid_trampoline_addr(SB)/4, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpriority_trampoline_addr(SB)/4, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrlimit_trampoline_addr(SB)/4, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrtable(SB)
+
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrtable_trampoline_addr(SB)/4, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrusage_trampoline_addr(SB)/4, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsid_trampoline_addr(SB)/4, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $4
+DATA	·libc_gettimeofday_trampoline_addr(SB)/4, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getuid_trampoline_addr(SB)/4, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_issetugid_trampoline_addr(SB)/4, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kill_trampoline_addr(SB)/4, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kqueue_trampoline_addr(SB)/4, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lchown_trampoline_addr(SB)/4, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $4
+DATA	·libc_link_trampoline_addr(SB)/4, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_linkat(SB)
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_linkat_trampoline_addr(SB)/4, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $4
+DATA	·libc_listen_trampoline_addr(SB)/4, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lstat_trampoline_addr(SB)/4, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkdir_trampoline_addr(SB)/4, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdirat(SB)
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkdirat_trampoline_addr(SB)/4, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkfifo_trampoline_addr(SB)/4, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifoat(SB)
+
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkfifoat_trampoline_addr(SB)/4, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mknod_trampoline_addr(SB)/4, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknodat(SB)
+
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $4
+DATA	·libc_nanosleep_trampoline_addr(SB)/4, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $4
+DATA	·libc_open_trampoline_addr(SB)/4, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_openat_trampoline_addr(SB)/4, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pathconf_trampoline_addr(SB)/4, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pread_trampoline_addr(SB)/4, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pwrite_trampoline_addr(SB)/4, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $4
+DATA	·libc_read_trampoline_addr(SB)/4, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_readlink_trampoline_addr(SB)/4, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlinkat(SB)
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_readlinkat_trampoline_addr(SB)/4, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $4
+DATA	·libc_rename_trampoline_addr(SB)/4, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_renameat(SB)
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_renameat_trampoline_addr(SB)/4, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $4
+DATA	·libc_revoke_trampoline_addr(SB)/4, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_rmdir_trampoline_addr(SB)/4, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lseek_trampoline_addr(SB)/4, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $4
+DATA	·libc_select_trampoline_addr(SB)/4, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setegid_trampoline_addr(SB)/4, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_seteuid_trampoline_addr(SB)/4, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setgid_trampoline_addr(SB)/4, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setlogin_trampoline_addr(SB)/4, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setpgid_trampoline_addr(SB)/4, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setpriority_trampoline_addr(SB)/4, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setregid_trampoline_addr(SB)/4, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setreuid_trampoline_addr(SB)/4, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresgid(SB)
+
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setresgid_trampoline_addr(SB)/4, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresuid(SB)
+
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrtable(SB)
+
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setrtable_trampoline_addr(SB)/4, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setsid_trampoline_addr(SB)/4, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $4
+DATA	·libc_settimeofday_trampoline_addr(SB)/4, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setuid_trampoline_addr(SB)/4, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_stat_trampoline_addr(SB)/4, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $4
+DATA	·libc_statfs_trampoline_addr(SB)/4, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_symlink_trampoline_addr(SB)/4, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlinkat(SB)
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_symlinkat_trampoline_addr(SB)/4, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sync_trampoline_addr(SB)/4, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $4
+DATA	·libc_truncate_trampoline_addr(SB)/4, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $4
+DATA	·libc_umask_trampoline_addr(SB)/4, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unlink_trampoline_addr(SB)/4, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unlinkat_trampoline_addr(SB)/4, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unmount_trampoline_addr(SB)/4, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $4
+DATA	·libc_write_trampoline_addr(SB)/4, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mmap_trampoline_addr(SB)/4, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munmap_trampoline_addr(SB)/4, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_utimensat_trampoline_addr(SB)/4, $libc_utimensat_trampoline<>(SB)
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
index 467971eed..f59b18a97 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
@@ -6,6 +6,7 @@
 
 package unix
 
+// Deprecated: Use libc wrappers instead of direct syscalls.
 const (
 	SYS_EXIT           = 1   // { void sys_exit(int rval); }
 	SYS_FORK           = 2   // { int sys_fork(void); }
diff --git a/vendor/golang.org/x/sys/windows/setupapi_windows.go b/vendor/golang.org/x/sys/windows/setupapi_windows.go
index 14027da3f..f8126482f 100644
--- a/vendor/golang.org/x/sys/windows/setupapi_windows.go
+++ b/vendor/golang.org/x/sys/windows/setupapi_windows.go
@@ -296,7 +296,7 @@ const (
 	// Flag to indicate that the sorting from the INF file should be used.
 	DI_INF_IS_SORTED DI_FLAGS = 0x00008000
 
-	// Flag to indicate that only the the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched.
+	// Flag to indicate that only the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched.
 	DI_ENUMSINGLEINF DI_FLAGS = 0x00010000
 
 	// Flag that prevents ConfigMgr from removing/re-enumerating devices during device
diff --git a/vendor/google.golang.org/api/internal/version.go b/vendor/google.golang.org/api/internal/version.go
index 4fc51d1b1..b5a685e70 100644
--- a/vendor/google.golang.org/api/internal/version.go
+++ b/vendor/google.golang.org/api/internal/version.go
@@ -5,4 +5,4 @@
 package internal
 
 // Version is the current tagged release of the library.
-const Version = "0.92.0"
+const Version = "0.93.0"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c445a7763..1aefd88e2 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -5,7 +5,7 @@ cloud.google.com/go/internal
 cloud.google.com/go/internal/optional
 cloud.google.com/go/internal/trace
 cloud.google.com/go/internal/version
-# cloud.google.com/go/compute v1.8.0
+# cloud.google.com/go/compute v1.9.0
 ## explicit; go 1.17
 cloud.google.com/go/compute/metadata
 # cloud.google.com/go/iam v0.3.0
@@ -35,7 +35,7 @@ github.com/VictoriaMetrics/metricsql/binaryop
 # github.com/VividCortex/ewma v1.2.0
 ## explicit; go 1.12
 github.com/VividCortex/ewma
-# github.com/aws/aws-sdk-go v1.44.76
+# github.com/aws/aws-sdk-go v1.44.81
 ## explicit; go 1.11
 github.com/aws/aws-sdk-go/aws
 github.com/aws/aws-sdk-go/aws/arn
@@ -170,11 +170,11 @@ github.com/klauspost/compress/internal/snapref
 github.com/klauspost/compress/zlib
 github.com/klauspost/compress/zstd
 github.com/klauspost/compress/zstd/internal/xxhash
-# github.com/mattn/go-colorable v0.1.12
-## explicit; go 1.13
+# github.com/mattn/go-colorable v0.1.13
+## explicit; go 1.15
 github.com/mattn/go-colorable
-# github.com/mattn/go-isatty v0.0.14
-## explicit; go 1.12
+# github.com/mattn/go-isatty v0.0.16
+## explicit; go 1.15
 github.com/mattn/go-isatty
 # github.com/mattn/go-runewidth v0.0.13
 ## explicit; go 1.9
@@ -302,10 +302,10 @@ golang.org/x/oauth2/google/internal/externalaccount
 golang.org/x/oauth2/internal
 golang.org/x/oauth2/jws
 golang.org/x/oauth2/jwt
-# golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
+# golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde
 ## explicit
 golang.org/x/sync/errgroup
-# golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
+# golang.org/x/sys v0.0.0-20220818161305-2296e01440c6
 ## explicit; go 1.17
 golang.org/x/sys/internal/unsafeheader
 golang.org/x/sys/unix
@@ -320,7 +320,7 @@ golang.org/x/text/unicode/norm
 ## explicit; go 1.17
 golang.org/x/xerrors
 golang.org/x/xerrors/internal
-# google.golang.org/api v0.92.0
+# google.golang.org/api v0.93.0
 ## explicit; go 1.15
 google.golang.org/api/googleapi
 google.golang.org/api/googleapi/transport
@@ -353,7 +353,7 @@ google.golang.org/appengine/internal/socket
 google.golang.org/appengine/internal/urlfetch
 google.golang.org/appengine/socket
 google.golang.org/appengine/urlfetch
-# google.golang.org/genproto v0.0.0-20220812140447-cec7f5303424
+# google.golang.org/genproto v0.0.0-20220819174105-e9f053255caa
 ## explicit; go 1.19
 google.golang.org/genproto/googleapis/api/annotations
 google.golang.org/genproto/googleapis/iam/v1


Test patch:
diff --git a/lib/promrelabel/if_expression_test.go b/lib/promrelabel/if_expression_test.go
index ce9f20290..18b654f4c 100644
--- a/lib/promrelabel/if_expression_test.go
+++ b/lib/promrelabel/if_expression_test.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
+	"strings"
 	"testing"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
@@ -188,6 +189,12 @@ func TestIfExpressionMismatch(t *testing.T) {
 }
 
 func parseMetricWithLabels(metricWithLabels string) ([]prompbmarshal.Label, error) {
+	stripDummyMetric := false
+	if strings.HasPrefix(metricWithLabels, "{") {
+		// Add a dummy metric name, since the parser needs it
+		metricWithLabels = "dummy_metric" + metricWithLabels
+		stripDummyMetric = true
+	}
 	// add a value to metricWithLabels, so it could be parsed by prometheus protocol parser.
 	s := metricWithLabels + " 123"
 	var rows prometheus.Rows
@@ -203,7 +210,7 @@ func parseMetricWithLabels(metricWithLabels string) ([]prompbmarshal.Label, erro
 	}
 	r := rows.Rows[0]
 	var lfs []prompbmarshal.Label
-	if r.Metric != "" {
+	if !stripDummyMetric {
 		lfs = append(lfs, prompbmarshal.Label{
 			Name:  "__name__",
 			Value: r.Metric,
diff --git a/lib/promrelabel/relabel_test.go b/lib/promrelabel/relabel_test.go
index 68ec973bf..52b501bc5 100644
--- a/lib/promrelabel/relabel_test.go
+++ b/lib/promrelabel/relabel_test.go
@@ -1,7 +1,6 @@
 package promrelabel
 
 import (
-	"reflect"
 	"testing"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
@@ -55,96 +54,50 @@ func TestLabelsToString(t *testing.T) {
 }
 
 func TestApplyRelabelConfigs(t *testing.T) {
-	f := func(config string, labels []prompbmarshal.Label, isFinalize bool, resultExpected []prompbmarshal.Label) {
+	f := func(config, metric string, isFinalize bool, resultExpected string) {
 		t.Helper()
 		pcs, err := ParseRelabelConfigsData([]byte(config), false)
 		if err != nil {
 			t.Fatalf("cannot parse %q: %s", config, err)
 		}
-		result := pcs.Apply(labels, 0, isFinalize)
-		if !reflect.DeepEqual(result, resultExpected) {
-			t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected)
+		labels, err := parseMetricWithLabels(metric)
+		if err != nil {
+			t.Fatalf("cannot parse %s: %s", metric, err)
+		}
+		resultLabels := pcs.Apply(labels, 0, isFinalize)
+		result := labelsToString(resultLabels)
+		if result != resultExpected {
+			t.Fatalf("unexpected result; got\n%s\nwant\n%s", result, resultExpected)
 		}
 	}
 	t.Run("empty_relabel_configs", func(t *testing.T) {
-		f("", nil, false, nil)
-		f("", nil, true, nil)
-		f("", []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		})
-		f("", []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "__name__",
-				Value: "xxx",
-			},
-			{
-				Name:  "__aaa",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "xxx",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		})
+		f("", `{}`, false, `{}`)
+		f("", `{}`, true, `{}`)
+		f("", `{foo="bar"}`, false, `{foo="bar"}`)
+		f("", `xxx{foo="bar",__aaa="yyy"}`, false, `xxx{__aaa="yyy",foo="bar"}`)
+		f("", `xxx{foo="bar",__aaa="yyy"}`, true, `xxx{foo="bar"}`)
 	})
 	t.Run("replace-miss", func(t *testing.T) {
 		f(`
 - action: replace
   target_label: bar
-`, nil, false, []prompbmarshal.Label{})
+`, `{}`, false, `{}`)
 		f(`
 - action: replace
   source_labels: ["foo"]
   target_label: bar
-`, nil, false, []prompbmarshal.Label{})
+`, `{}`, false, `{}`)
 		f(`
 - action: replace
   source_labels: ["foo"]
   target_label: "bar"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{xxx="yyy"}`)
 		f(`
 - action: replace
   source_labels: ["foo"]
   target_label: "bar"
   regex: ".+"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{xxx="yyy"}`)
 	})
 	t.Run("replace-if-miss", func(t *testing.T) {
 		f(`
@@ -153,17 +106,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: ["xxx", "foo"]
   target_label: "bar"
   replacement: "a-$1-b"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{xxx="yyy"}`)
 	})
 	t.Run("replace-hit", func(t *testing.T) {
 		f(`
@@ -171,21 +114,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: ["xxx", "foo"]
   target_label: "bar"
   replacement: "a-$1-b"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "a-yyy;-b",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{bar="a-yyy;-b",xxx="yyy"}`)
 	})
 	t.Run("replace-if-hit", func(t *testing.T) {
 		f(`
@@ -194,21 +123,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: ["xxx", "foo"]
   target_label: "bar"
   replacement: "a-$1-b"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "a-yyy;-b",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{bar="a-yyy;-b",xxx="yyy"}`)
 	})
 	t.Run("replace-remove-label-value-hit", func(t *testing.T) {
 		f(`
@@ -217,21 +132,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   target_label: "foo"
   regex: "xxx"
   replacement: ""
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "xxx",
-			},
-			{
-				Name:  "bar",
-				Value: "baz",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "baz",
-			},
-		})
+`, `{foo="xxx",bar="baz"}`, false, `{bar="baz"}`)
 	})
 	t.Run("replace-remove-label-value-miss", func(t *testing.T) {
 		f(`
@@ -240,25 +141,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   target_label: "foo"
   regex: "xxx"
   replacement: ""
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "bar",
-				Value: "baz",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "baz",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy",bar="baz"}`, false, `{bar="baz",foo="yyy"}`)
 	})
 	t.Run("replace-hit-remove-label", func(t *testing.T) {
 		f(`
@@ -267,21 +150,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   regex: "yyy;.+"
   target_label: "foo"
   replacement: ""
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",foo="bar"}`, false, `{xxx="yyy"}`)
 	})
 	t.Run("replace-miss-remove-label", func(t *testing.T) {
 		f(`
@@ -290,25 +159,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   regex: "yyy;.+"
   target_label: "foo"
   replacement: ""
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyyz",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyyz",
-			},
-		})
+`, `{xxx="yyyz",foo="bar"}`, false, `{foo="bar",xxx="yyyz"}`)
 	})
 	t.Run("replace-hit-target-label-with-capture-group", func(t *testing.T) {
 		f(`
@@ -316,64 +167,30 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: ["xxx", "foo"]
   target_label: "bar-$1"
   replacement: "a-$1-b"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "bar-yyy;",
-				Value: "a-yyy;-b",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{bar-yyy;="a-yyy;-b",xxx="yyy"}`)
 	})
 	t.Run("replace_all-miss", func(t *testing.T) {
 		f(`
 - action: replace_all
   source_labels: [foo]
   target_label: "bar"
-`, nil, false, []prompbmarshal.Label{})
+`, `{}`, false, `{}`)
 		f(`
 - action: replace_all
   source_labels: ["foo"]
   target_label: "bar"
-`, nil, false, []prompbmarshal.Label{})
+`, `{}`, false, `{}`)
 		f(`
 - action: replace_all
   source_labels: ["foo"]
   target_label: "bar"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{xxx="yyy"}`)
 		f(`
 - action: replace_all
   source_labels: ["foo"]
   target_label: "bar"
   regex: ".+"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{xxx="yyy"}`)
 	})
 	t.Run("replace_all-if-miss", func(t *testing.T) {
 		f(`
@@ -383,17 +200,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   target_label: "xxx"
   regex: "-"
   replacement: "."
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "a-b-c",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "a-b-c",
-			},
-		})
+`, `{xxx="a-b-c"}`, false, `{xxx="a-b-c"}`)
 	})
 	t.Run("replace_all-hit", func(t *testing.T) {
 		f(`
@@ -402,17 +209,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   target_label: "xxx"
   regex: "-"
   replacement: "."
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "a-b-c",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "a.b.c",
-			},
-		})
+`, `{xxx="a-b-c"}`, false, `{xxx="a.b.c"}`)
 	})
 	t.Run("replace_all-if-hit", func(t *testing.T) {
 		f(`
@@ -422,17 +219,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   target_label: "xxx"
   regex: "-"
   replacement: "."
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "a-b-c",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "a.b.c",
-			},
-		})
+`, `{xxx="a-b-c"}`, false, `{xxx="a.b.c"}`)
 	})
 	t.Run("replace_all-regex-hit", func(t *testing.T) {
 		f(`
@@ -441,17 +228,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   target_label: "xxx"
   regex: "(;)"
   replacement: "-$1-"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "y;y",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "y-;-y-;-",
-			},
-		})
+`, `{xxx="y;y"}`, false, `{xxx="y-;-y-;-"}`)
 	})
 	t.Run("replace-add-multi-labels", func(t *testing.T) {
 		f(`
@@ -463,33 +240,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: ["bar"]
   target_label: "zar"
   replacement: "b-$1"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "instance",
-				Value: "a.bc",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "a-yyy",
-			},
-			{
-				Name:  "instance",
-				Value: "a.bc",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "zar",
-				Value: "b-a-yyy",
-			},
-		})
+`, `{xxx="yyy",instance="a.bc"}`, true, `{bar="a-yyy",instance="a.bc",xxx="yyy",zar="b-a-yyy"}`)
 	})
 	t.Run("replace-self", func(t *testing.T) {
 		f(`
@@ -497,181 +248,84 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: ["foo"]
   target_label: "foo"
   replacement: "a-$1"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "aaxx",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "a-aaxx",
-			},
-		})
+`, `{foo="aaxx"}`, true, `{foo="a-aaxx"}`)
 	})
 	t.Run("replace-missing-source", func(t *testing.T) {
 		f(`
 - action: replace
   target_label: foo
   replacement: "foobar"
-`, []prompbmarshal.Label{}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "foobar",
-			},
-		})
+`, `{}`, true, `{foo="foobar"}`)
 	})
 	t.Run("keep_if_equal-miss", func(t *testing.T) {
 		f(`
 - action: keep_if_equal
   source_labels: ["foo", "bar"]
-`, nil, true, nil)
+`, `{}`, true, `{}`)
 		f(`
 - action: keep_if_equal
   source_labels: ["xxx", "bar"]
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `{xxx="yyy"}`, true, `{}`)
 	})
 	t.Run("keep_if_equal-hit", func(t *testing.T) {
 		f(`
 - action: keep_if_equal
   source_labels: ["xxx", "bar"]
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "bar",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "yyy",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",bar="yyy"}`, true, `{bar="yyy",xxx="yyy"}`)
 	})
 	t.Run("drop_if_equal-miss", func(t *testing.T) {
 		f(`
 - action: drop_if_equal
   source_labels: ["foo", "bar"]
-`, nil, true, nil)
+`, `{}`, true, `{}`)
 		f(`
 - action: drop_if_equal
   source_labels: ["xxx", "bar"]
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, true, `{xxx="yyy"}`)
 	})
 	t.Run("drop_if_equal-hit", func(t *testing.T) {
 		f(`
 - action: drop_if_equal
   source_labels: [xxx, bar]
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "bar",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `{xxx="yyy",bar="yyy"}`, true, `{}`)
 	})
 	t.Run("keep-miss", func(t *testing.T) {
 		f(`
 - action: keep
   source_labels: [foo]
   regex: ".+"
-`, nil, true, nil)
+`, `{}`, true, `{}`)
 		f(`
 - action: keep
   source_labels: [foo]
   regex: ".+"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `{xxx="yyy"}`, true, `{}`)
 	})
 	t.Run("keep-if-miss", func(t *testing.T) {
 		f(`
 - action: keep
   if: '{foo="bar"}'
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{})
+`, `{foo="yyy"}`, false, `{}`)
 	})
 	t.Run("keep-if-hit", func(t *testing.T) {
 		f(`
 - action: keep
   if: '{foo="yyy"}'
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, false, `{foo="yyy"}`)
 	})
 	t.Run("keep-hit", func(t *testing.T) {
 		f(`
 - action: keep
   source_labels: [foo]
   regex: "yyy"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, false, `{foo="yyy"}`)
 	})
 	t.Run("keep-hit-regexp", func(t *testing.T) {
 		f(`
 - action: keep
   source_labels: ["foo"]
   regex: ".+"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, false, `{foo="yyy"}`)
 	})
 	t.Run("keep_metrics-miss", func(t *testing.T) {
 		f(`
@@ -679,39 +333,19 @@ func TestApplyRelabelConfigs(t *testing.T) {
   regex:
   - foo
   - bar
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "xxx",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `xxx`, true, `{}`)
 	})
 	t.Run("keep_metrics-if-miss", func(t *testing.T) {
 		f(`
 - action: keep_metrics
   if: 'bar'
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `foo`, true, `{}`)
 	})
 	t.Run("keep_metrics-if-hit", func(t *testing.T) {
 		f(`
 - action: keep_metrics
   if: 'foo'
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		})
+`, `foo`, true, `foo`)
 	})
 	t.Run("keep_metrics-hit", func(t *testing.T) {
 		f(`
@@ -719,90 +353,45 @@ func TestApplyRelabelConfigs(t *testing.T) {
   regex:
   - foo
   - bar
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		})
+`, `foo`, true, `foo`)
 	})
 	t.Run("drop-miss", func(t *testing.T) {
 		f(`
 - action: drop
   source_labels: [foo]
   regex: ".+"
-`, nil, false, nil)
+`, `{}`, false, `{}`)
 		f(`
 - action: drop
   source_labels: [foo]
   regex: ".+"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, true, `{xxx="yyy"}`)
 	})
 	t.Run("drop-if-miss", func(t *testing.T) {
 		f(`
 - action: drop
   if: '{foo="bar"}'
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, true, `{foo="yyy"}`)
 	})
 	t.Run("drop-if-hit", func(t *testing.T) {
 		f(`
 - action: drop
   if: '{foo="yyy"}'
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `{foo="yyy"}`, true, `{}`)
 	})
 	t.Run("drop-hit", func(t *testing.T) {
 		f(`
 - action: drop
   source_labels: [foo]
   regex: yyy
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `{foo="yyy"}`, true, `{}`)
 	})
 	t.Run("drop-hit-regexp", func(t *testing.T) {
 		f(`
 - action: drop
   source_labels: [foo]
   regex: ".+"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `{foo="yyy"}`, true, `{}`)
 	})
 	t.Run("drop_metrics-miss", func(t *testing.T) {
 		f(`
@@ -810,44 +399,19 @@ func TestApplyRelabelConfigs(t *testing.T) {
   regex:
   - foo
   - bar
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "xxx",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "xxx",
-			},
-		})
+`, `xxx`, true, `xxx`)
 	})
 	t.Run("drop_metrics-if-miss", func(t *testing.T) {
 		f(`
 - action: drop_metrics
   if: bar
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		})
+`, `foo`, true, `foo`)
 	})
 	t.Run("drop_metrics-if-hit", func(t *testing.T) {
 		f(`
 - action: drop_metrics
   if: foo
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `foo`, true, `{}`)
 	})
 	t.Run("drop_metrics-hit", func(t *testing.T) {
 		f(`
@@ -855,12 +419,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   regex:
   - foo
   - bar
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo",
-			},
-		}, true, []prompbmarshal.Label{})
+`, `foo`, true, `{}`)
 	})
 	t.Run("hashmod-miss", func(t *testing.T) {
 		f(`
@@ -868,21 +427,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: [foo]
   target_label: aaa
   modulus: 123
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "81",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy"}`, false, `{aaa="81",xxx="yyy"}`)
 	})
 	t.Run("hashmod-if-miss", func(t *testing.T) {
 		f(`
@@ -891,17 +436,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: [foo]
   target_label: aaa
   modulus: 123
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, true, `{foo="yyy"}`)
 	})
 	t.Run("hashmod-if-hit", func(t *testing.T) {
 		f(`
@@ -910,21 +445,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: [foo]
   target_label: aaa
   modulus: 123
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "73",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, true, `{aaa="73",foo="yyy"}`)
 	})
 	t.Run("hashmod-hit", func(t *testing.T) {
 		f(`
@@ -932,21 +453,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   source_labels: [foo]
   target_label: aaa
   modulus: 123
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "73",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-		})
+`, `{foo="yyy"}`, true, `{aaa="73",foo="yyy"}`)
 	})
 	t.Run("labelmap-copy-label-if-miss", func(t *testing.T) {
 		f(`
@@ -954,25 +461,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   if: '{foo="yyy",foobar="aab"}'
   regex: "foo"
   replacement: "bar"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo="yyy",foobar="aaa"}`, true, `{foo="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap-copy-label-if-hit", func(t *testing.T) {
 		f(`
@@ -980,143 +469,33 @@ func TestApplyRelabelConfigs(t *testing.T) {
   if: '{foo="yyy",foobar="aaa"}'
   regex: "foo"
   replacement: "bar"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "yyy",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo="yyy",foobar="aaa"}`, true, `{bar="yyy",foo="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap-copy-label", func(t *testing.T) {
 		f(`
 - action: labelmap
   regex: "foo"
   replacement: "bar"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "yyy",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo="yyy",foobar="aaa"}`, true, `{bar="yyy",foo="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap-remove-prefix-dot-star", func(t *testing.T) {
 		f(`
 - action: labelmap
   regex: "foo(.*)"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xoo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "aaa",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-			{
-				Name:  "xoo",
-				Value: "yyy",
-			},
-		})
+`, `{xoo="yyy",foobar="aaa"}`, true, `{bar="aaa",foobar="aaa",xoo="yyy"}`)
 	})
 	t.Run("labelmap-remove-prefix-dot-plus", func(t *testing.T) {
 		f(`
 - action: labelmap
   regex: "foo(.+)"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo="yyy",foobar="aaa"}`, true, `{bar="aaa",foo="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap-regex", func(t *testing.T) {
 		f(`
 - action: labelmap
   regex: "foo(.+)"
   replacement: "$1-x"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "bar-x",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo="yyy",foobar="aaa"}`, true, `{bar-x="aaa",foo="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap_all-if-miss", func(t *testing.T) {
 		f(`
@@ -1124,25 +503,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   if: foobar
   regex: "\\."
   replacement: "-"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo.bar.baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo.bar.baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo.bar.baz="yyy",foobar="aaa"}`, true, `{foo.bar.baz="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap_all-if-hit", func(t *testing.T) {
 		f(`
@@ -1150,473 +511,119 @@ func TestApplyRelabelConfigs(t *testing.T) {
   if: '{foo.bar.baz="yyy"}'
   regex: "\\."
   replacement: "-"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo.bar.baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo-bar-baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo.bar.baz="yyy",foobar="aaa"}`, true, `{foo-bar-baz="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap_all", func(t *testing.T) {
 		f(`
 - action: labelmap_all
   regex: "\\."
   replacement: "-"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo.bar.baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo-bar-baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foobar",
-				Value: "aaa",
-			},
-		})
+`, `{foo.bar.baz="yyy",foobar="aaa"}`, true, `{foo-bar-baz="yyy",foobar="aaa"}`)
 	})
 	t.Run("labelmap_all-regexp", func(t *testing.T) {
 		f(`
 - action: labelmap_all
   regex: "ba(.)"
   replacement: "${1}ss"
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo.bar.baz",
-				Value: "yyy",
-			},
-			{
-				Name:  "foozar",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo.rss.zss",
-				Value: "yyy",
-			},
-			{
-				Name:  "foozar",
-				Value: "aaa",
-			},
-		})
+`, `{foo.bar.baz="yyy",foozar="aaa"}`, true, `{foo.rss.zss="yyy",foozar="aaa"}`)
 	})
 	t.Run("labeldrop", func(t *testing.T) {
 		f(`
 - action: labeldrop
   regex: dropme
-`, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "bbb",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "bbb",
-			},
-		})
+`, `{aaa="bbb"}`, true, `{aaa="bbb"}`)
 		// if-miss
 		f(`
 - action: labeldrop
   if: foo
   regex: dropme
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "dropme",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme="aaa",foo="bar"}`, false, `{dropme="aaa",foo="bar",xxx="yyy"}`)
 		// if-hit
 		f(`
 - action: labeldrop
   if: '{xxx="yyy"}'
   regex: dropme
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme="aaa",foo="bar"}`, false, `{foo="bar",xxx="yyy"}`)
 		f(`
 - action: labeldrop
   regex: dropme
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme="aaa",foo="bar"}`, false, `{foo="bar",xxx="yyy"}`)
 		// regex in single quotes
 		f(`
 - action: labeldrop
   regex: 'dropme'
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme",
-				Value: "aaa",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme="aaa"}`, false, `{xxx="yyy"}`)
 		// regex in double quotes
 		f(`
 - action: labeldrop
   regex: "dropme"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme",
-				Value: "aaa",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme="aaa"}`, false, `{xxx="yyy"}`)
 	})
 	t.Run("labeldrop-prefix", func(t *testing.T) {
 		f(`
 - action: labeldrop
   regex: "dropme.*"
-`, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "bbb",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "bbb",
-			},
-		})
+`, `{aaa="bbb"}`, true, `{aaa="bbb"}`)
 		f(`
 - action: labeldrop
   regex: "dropme(.+)"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme-please",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme-please="aaa",foo="bar"}`, false, `{foo="bar",xxx="yyy"}`)
 	})
 	t.Run("labeldrop-regexp", func(t *testing.T) {
 		f(`
 - action: labeldrop
   regex: ".*dropme.*"
-`, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "bbb",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "aaa",
-				Value: "bbb",
-			},
-		})
+`, `{aaa="bbb"}`, true, `{aaa="bbb"}`)
 		f(`
 - action: labeldrop
   regex: ".*dropme.*"
-`, []prompbmarshal.Label{
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-			{
-				Name:  "dropme-please",
-				Value: "aaa",
-			},
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-			{
-				Name:  "xxx",
-				Value: "yyy",
-			},
-		})
+`, `{xxx="yyy",dropme-please="aaa",foo="bar"}`, false, `{foo="bar",xxx="yyy"}`)
 	})
 	t.Run("labelkeep", func(t *testing.T) {
 		f(`
 - action: labelkeep
   regex: "keepme"
-`, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-		})
+`, `{keepme="aaa"}`, true, `{keepme="aaa"}`)
 		// if-miss
 		f(`
 - action: labelkeep
   if: '{aaaa="awefx"}'
   regex: keepme
-`, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-			{
-				Name:  "aaaa",
-				Value: "awef",
-			},
-			{
-				Name:  "keepme-aaa",
-				Value: "234",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "aaaa",
-				Value: "awef",
-			},
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-			{
-				Name:  "keepme-aaa",
-				Value: "234",
-			},
-		})
+`, `{keepme="aaa",aaaa="awef",keepme-aaa="234"}`, false, `{aaaa="awef",keepme="aaa",keepme-aaa="234"}`)
 		// if-hit
 		f(`
 - action: labelkeep
   if: '{aaaa="awef"}'
   regex: keepme
-`, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-			{
-				Name:  "aaaa",
-				Value: "awef",
-			},
-			{
-				Name:  "keepme-aaa",
-				Value: "234",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-		})
+`, `{keepme="aaa",aaaa="awef",keepme-aaa="234"}`, false, `{keepme="aaa"}`)
 		f(`
 - action: labelkeep
   regex: keepme
-`, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-			{
-				Name:  "aaaa",
-				Value: "awef",
-			},
-			{
-				Name:  "keepme-aaa",
-				Value: "234",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-		})
+`, `{keepme="aaa",aaaa="awef",keepme-aaa="234"}`, false, `{keepme="aaa"}`)
 	})
 	t.Run("labelkeep-regexp", func(t *testing.T) {
 		f(`
 - action: labelkeep
   regex: "keepme.*"
-`, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-		})
+`, `{keepme="aaa"}`, true, `{keepme="aaa"}`)
 		f(`
 - action: labelkeep
   regex: "keepme.*"
-`, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-			{
-				Name:  "aaaa",
-				Value: "awef",
-			},
-			{
-				Name:  "keepme-aaa",
-				Value: "234",
-			},
-		}, false, []prompbmarshal.Label{
-			{
-				Name:  "keepme",
-				Value: "aaa",
-			},
-			{
-				Name:  "keepme-aaa",
-				Value: "234",
-			},
-		})
+`, `{keepme="aaa",aaaa="awef",keepme-aaa="234"}`, false, `{keepme="aaa",keepme-aaa="234"}`)
 	})
 	t.Run("upper-lower-case", func(t *testing.T) {
 		f(`
 - action: uppercase
   source_labels: ["foo"]
   target_label: foo
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "bar",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "BAR",
-			},
-		})
+`, `{foo="bar"}`, true, `{foo="BAR"}`)
 		f(`
 - action: lowercase
   source_labels: ["foo", "bar"]
   target_label: baz
 - action: labeldrop
   regex: foo|bar
-`, []prompbmarshal.Label{
-			{
-				Name:  "foo",
-				Value: "BaR",
-			},
-			{
-				Name:  "bar",
-				Value: "fOO",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "baz",
-				Value: "bar;foo",
-			},
-		})
+`, `{foo="BaR",bar="fOO"}`, true, `{baz="bar;foo"}`)
 		f(`
 - action: lowercase
   source_labels: ["foo"]
@@ -1624,17 +631,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
 - action: uppercase
   source_labels: ["bar"]
   target_label: baz
-`, []prompbmarshal.Label{
-			{
-				Name:  "qux",
-				Value: "quux",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "qux",
-				Value: "quux",
-			},
-		})
+`, `{qux="quux"}`, true, `{qux="quux"}`)
 	})
 	t.Run("graphite-match", func(t *testing.T) {
 		f(`
@@ -1643,21 +640,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
   labels:
     __name__: aaa
     job: ${1}-zz
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo.bar.baz",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "aaa",
-			},
-			{
-				Name:  "job",
-				Value: "bar-zz",
-			},
-		})
+`, `foo.bar.baz`, true, `aaa{job="bar-zz"}`)
 	})
 	t.Run("graphite-mismatch", func(t *testing.T) {
 		f(`
@@ -1666,120 +649,80 @@ func TestApplyRelabelConfigs(t *testing.T) {
   labels:
     __name__: aaa
     job: ${1}-zz
-`, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo.bar.bazz",
-			},
-		}, true, []prompbmarshal.Label{
-			{
-				Name:  "__name__",
-				Value: "foo.bar.bazz",
-			},
-		})
+`, `foo.bar.bazz`, true, `foo.bar.bazz`)
+	})
+	t.Run("replacement-with-label-refs", func(t *testing.T) {
+		// no regex
+		f(`
+- target_label: abc
+  replacement: "{{__name__}}.{{foo}}"
+`, `qwe{foo="bar",baz="aaa"}`, true, `qwe{abc="qwe.bar",baz="aaa",foo="bar"}`)
+		// with regex
+		f(`
+- target_label: abc
+  replacement: "{{__name__}}.{{foo}}.$1"
+  source_labels: [baz]
+  regex: "a(.+)"
+`, `qwe{foo="bar",baz="aaa"}`, true, `qwe{abc="qwe.bar.aa",baz="aaa",foo="bar"}`)
 	})
 }
 
 func TestFinalizeLabels(t *testing.T) {
-	f := func(labels, resultExpected []prompbmarshal.Label) {
+	f := func(metric, resultExpected string) {
 		t.Helper()
-		result := FinalizeLabels(nil, labels)
-		if !reflect.DeepEqual(result, resultExpected) {
-			t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected)
+		labels, err := parseMetricWithLabels(metric)
+		if err != nil {
+			t.Fatalf("cannot parse %s: %s", metric, err)
+		}
+		resultLabels := FinalizeLabels(nil, labels)
+		result := labelsToString(resultLabels)
+		if result != resultExpected {
+			t.Fatalf("unexpected result; got\n%s\nwant\n%s", result, resultExpected)
 		}
 	}
-	f(nil, nil)
-	f([]prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-		{
-			Name:  "__aaa",
-			Value: "ass",
-		},
-		{
-			Name:  "instance",
-			Value: "foo.com",
-		},
-	}, []prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-		{
-			Name:  "instance",
-			Value: "foo.com",
-		},
-	})
-	f([]prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-		{
-			Name:  "instance",
-			Value: "ass",
-		},
-		{
-			Name:  "__address__",
-			Value: "foo.com",
-		},
-	}, []prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-		{
-			Name:  "instance",
-			Value: "ass",
-		},
-	})
+	f(`{}`, `{}`)
+	f(`{foo="bar",__aaa="ass",instance="foo.com"}`, `{foo="bar",instance="foo.com"}`)
+	f(`{foo="bar",instance="ass",__address__="foo.com"}`, `{foo="bar",instance="ass"}`)
+	f(`{foo="bar",abc="def",__address__="foo.com"}`, `{abc="def",foo="bar"}`)
 }
 
 func TestRemoveMetaLabels(t *testing.T) {
-	f := func(labels, resultExpected []prompbmarshal.Label) {
+	f := func(metric, resultExpected string) {
 		t.Helper()
-		result := RemoveMetaLabels(nil, labels)
-		if !reflect.DeepEqual(result, resultExpected) {
-			t.Fatalf("unexpected result of RemoveMetaLabels;\ngot\n%v\nwant\n%v", result, resultExpected)
+		labels, err := parseMetricWithLabels(metric)
+		if err != nil {
+			t.Fatalf("cannot parse %s: %s", metric, err)
+		}
+		resultLabels := RemoveMetaLabels(nil, labels)
+		result := labelsToString(resultLabels)
+		if result != resultExpected {
+			t.Fatalf("unexpected result of RemoveMetaLabels;\ngot\n%s\nwant\n%s", result, resultExpected)
 		}
 	}
-	f(nil, nil)
-	f([]prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-	}, []prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-	})
-	f([]prompbmarshal.Label{
-		{
-			Name:  "__meta_foo",
-			Value: "bar",
-		},
-	}, nil)
-	f([]prompbmarshal.Label{
-		{
-			Name:  "__meta_foo",
-			Value: "bdffr",
-		},
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-		{
-			Name:  "__meta_xxx",
-			Value: "basd",
-		},
-	}, []prompbmarshal.Label{
-		{
-			Name:  "foo",
-			Value: "bar",
-		},
-	})
+	f(`{}`, `{}`)
+	f(`{foo="bar"}`, `{foo="bar"}`)
+	f(`{__meta_foo="bar"}`, `{}`)
+	f(`{__meta_foo="bdffr",foo="bar",__meta_xxx="basd"}`, `{foo="bar"}`)
+}
+
+func TestFillLabelReferences(t *testing.T) {
+	f := func(replacement, metric, resultExpected string) {
+		t.Helper()
+		labels, err := parseMetricWithLabels(metric)
+		if err != nil {
+			t.Fatalf("cannot parse %s: %s", metric, err)
+		}
+		result := fillLabelReferences(nil, replacement, labels)
+		if string(result) != resultExpected {
+			t.Fatalf("unexpected result; got\n%q\nwant\n%q", result, resultExpected)
+		}
+	}
+	f(``, `foo{bar="baz"}`, ``)
+	f(`abc`, `foo{bar="baz"}`, `abc`)
+	f(`foo{{bar`, `foo{bar="baz"}`, `foo{{bar`)
+	f(`foo-$1`, `foo{bar="baz"}`, `foo-$1`)
+	f(`foo{{bar}}`, `foo{bar="baz"}`, `foobaz`)
+	f(`{{bar}}`, `foo{bar="baz"}`, `baz`)
+	f(`{{bar}}-aa`, `foo{bar="baz"}`, `baz-aa`)
+	f(`{{bar}}-aa{{__name__}}.{{bar}}{{non-existing-label}}`, `foo{bar="baz"}`, `baz-aafoo.baz`)
 }