162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci#ifndef _GNU_SOURCE 362306a36Sopenharmony_ci#define _GNU_SOURCE 462306a36Sopenharmony_ci#endif 562306a36Sopenharmony_ci#include <link.h> 662306a36Sopenharmony_ci#include <stdio.h> 762306a36Sopenharmony_ci#include <stdlib.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistruct Statistics { 1062306a36Sopenharmony_ci unsigned long long load_address; 1162306a36Sopenharmony_ci unsigned long long alignment; 1262306a36Sopenharmony_ci}; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciint ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci struct Statistics *stats = (struct Statistics *) data; 1762306a36Sopenharmony_ci int i; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci if (info->dlpi_name != NULL && info->dlpi_name[0] != '\0') { 2062306a36Sopenharmony_ci // Ignore headers from other than the executable. 2162306a36Sopenharmony_ci return 2; 2262306a36Sopenharmony_ci } 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci stats->load_address = (unsigned long long) info->dlpi_addr; 2562306a36Sopenharmony_ci stats->alignment = 0; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci for (i = 0; i < info->dlpi_phnum; i++) { 2862306a36Sopenharmony_ci if (info->dlpi_phdr[i].p_type != PT_LOAD) 2962306a36Sopenharmony_ci continue; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci if (info->dlpi_phdr[i].p_align > stats->alignment) 3262306a36Sopenharmony_ci stats->alignment = info->dlpi_phdr[i].p_align; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci return 1; // Terminate dl_iterate_phdr. 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ciint main(int argc, char **argv) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci struct Statistics extracted; 4162306a36Sopenharmony_ci unsigned long long misalign; 4262306a36Sopenharmony_ci int ret; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci ret = dl_iterate_phdr(ExtractStatistics, &extracted); 4562306a36Sopenharmony_ci if (ret != 1) { 4662306a36Sopenharmony_ci fprintf(stderr, "FAILED\n"); 4762306a36Sopenharmony_ci return 1; 4862306a36Sopenharmony_ci } 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (extracted.alignment == 0) { 5162306a36Sopenharmony_ci fprintf(stderr, "No alignment found\n"); 5262306a36Sopenharmony_ci return 1; 5362306a36Sopenharmony_ci } else if (extracted.alignment & (extracted.alignment - 1)) { 5462306a36Sopenharmony_ci fprintf(stderr, "Alignment is not a power of 2\n"); 5562306a36Sopenharmony_ci return 1; 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci misalign = extracted.load_address & (extracted.alignment - 1); 5962306a36Sopenharmony_ci if (misalign) { 6062306a36Sopenharmony_ci printf("alignment = %llu, load_address = %llu\n", 6162306a36Sopenharmony_ci extracted.alignment, extracted.load_address); 6262306a36Sopenharmony_ci fprintf(stderr, "FAILED\n"); 6362306a36Sopenharmony_ci return 1; 6462306a36Sopenharmony_ci } 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci fprintf(stderr, "PASS\n"); 6762306a36Sopenharmony_ci return 0; 6862306a36Sopenharmony_ci} 69