18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#ifndef _GNU_SOURCE 38c2ecf20Sopenharmony_ci#define _GNU_SOURCE 48c2ecf20Sopenharmony_ci#endif 58c2ecf20Sopenharmony_ci#include <link.h> 68c2ecf20Sopenharmony_ci#include <stdio.h> 78c2ecf20Sopenharmony_ci#include <stdlib.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct Statistics { 108c2ecf20Sopenharmony_ci unsigned long long load_address; 118c2ecf20Sopenharmony_ci unsigned long long alignment; 128c2ecf20Sopenharmony_ci}; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciint ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci struct Statistics *stats = (struct Statistics *) data; 178c2ecf20Sopenharmony_ci int i; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci if (info->dlpi_name != NULL && info->dlpi_name[0] != '\0') { 208c2ecf20Sopenharmony_ci // Ignore headers from other than the executable. 218c2ecf20Sopenharmony_ci return 2; 228c2ecf20Sopenharmony_ci } 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci stats->load_address = (unsigned long long) info->dlpi_addr; 258c2ecf20Sopenharmony_ci stats->alignment = 0; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci for (i = 0; i < info->dlpi_phnum; i++) { 288c2ecf20Sopenharmony_ci if (info->dlpi_phdr[i].p_type != PT_LOAD) 298c2ecf20Sopenharmony_ci continue; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci if (info->dlpi_phdr[i].p_align > stats->alignment) 328c2ecf20Sopenharmony_ci stats->alignment = info->dlpi_phdr[i].p_align; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci return 1; // Terminate dl_iterate_phdr. 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciint main(int argc, char **argv) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci struct Statistics extracted; 418c2ecf20Sopenharmony_ci unsigned long long misalign; 428c2ecf20Sopenharmony_ci int ret; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci ret = dl_iterate_phdr(ExtractStatistics, &extracted); 458c2ecf20Sopenharmony_ci if (ret != 1) { 468c2ecf20Sopenharmony_ci fprintf(stderr, "FAILED\n"); 478c2ecf20Sopenharmony_ci return 1; 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci if (extracted.alignment == 0) { 518c2ecf20Sopenharmony_ci fprintf(stderr, "No alignment found\n"); 528c2ecf20Sopenharmony_ci return 1; 538c2ecf20Sopenharmony_ci } else if (extracted.alignment & (extracted.alignment - 1)) { 548c2ecf20Sopenharmony_ci fprintf(stderr, "Alignment is not a power of 2\n"); 558c2ecf20Sopenharmony_ci return 1; 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci misalign = extracted.load_address & (extracted.alignment - 1); 598c2ecf20Sopenharmony_ci if (misalign) { 608c2ecf20Sopenharmony_ci printf("alignment = %llu, load_address = %llu\n", 618c2ecf20Sopenharmony_ci extracted.alignment, extracted.load_address); 628c2ecf20Sopenharmony_ci fprintf(stderr, "FAILED\n"); 638c2ecf20Sopenharmony_ci return 1; 648c2ecf20Sopenharmony_ci } 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci fprintf(stderr, "PASS\n"); 678c2ecf20Sopenharmony_ci return 0; 688c2ecf20Sopenharmony_ci} 69