linux/tools/testing/selftests/exec/load_address.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#ifndef _GNU_SOURCE
   3#define _GNU_SOURCE
   4#endif
   5#include <link.h>
   6#include <stdio.h>
   7#include <stdlib.h>
   8
   9struct Statistics {
  10        unsigned long long load_address;
  11        unsigned long long alignment;
  12};
  13
  14int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data)
  15{
  16        struct Statistics *stats = (struct Statistics *) data;
  17        int i;
  18
  19        if (info->dlpi_name != NULL && info->dlpi_name[0] != '\0') {
  20                // Ignore headers from other than the executable.
  21                return 2;
  22        }
  23
  24        stats->load_address = (unsigned long long) info->dlpi_addr;
  25        stats->alignment = 0;
  26
  27        for (i = 0; i < info->dlpi_phnum; i++) {
  28                if (info->dlpi_phdr[i].p_type != PT_LOAD)
  29                        continue;
  30
  31                if (info->dlpi_phdr[i].p_align > stats->alignment)
  32                        stats->alignment = info->dlpi_phdr[i].p_align;
  33        }
  34
  35        return 1;  // Terminate dl_iterate_phdr.
  36}
  37
  38int main(int argc, char **argv)
  39{
  40        struct Statistics extracted;
  41        unsigned long long misalign;
  42        int ret;
  43
  44        ret = dl_iterate_phdr(ExtractStatistics, &extracted);
  45        if (ret != 1) {
  46                fprintf(stderr, "FAILED\n");
  47                return 1;
  48        }
  49
  50        if (extracted.alignment == 0) {
  51                fprintf(stderr, "No alignment found\n");
  52                return 1;
  53        } else if (extracted.alignment & (extracted.alignment - 1)) {
  54                fprintf(stderr, "Alignment is not a power of 2\n");
  55                return 1;
  56        }
  57
  58        misalign = extracted.load_address & (extracted.alignment - 1);
  59        if (misalign) {
  60                printf("alignment = %llu, load_address = %llu\n",
  61                        extracted.alignment, extracted.load_address);
  62                fprintf(stderr, "FAILED\n");
  63                return 1;
  64        }
  65
  66        fprintf(stderr, "PASS\n");
  67        return 0;
  68}
  69