pcom.c revision 12927:a27c46eb192b
112256Sgoetz/* 212256Sgoetz * CDDL HEADER START 312256Sgoetz * 412256Sgoetz * The contents of this file are subject to the terms of the 512256Sgoetz * Common Development and Distribution License (the "License"). 612256Sgoetz * You may not use this file except in compliance with the License. 712256Sgoetz * 812256Sgoetz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 912256Sgoetz * or http://www.opensolaris.org/os/licensing. 1012256Sgoetz * See the License for the specific language governing permissions 1112256Sgoetz * and limitations under the License. 1212256Sgoetz * 1312256Sgoetz * When distributing Covered Code, include this CDDL HEADER in each 1412256Sgoetz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1512256Sgoetz * If applicable, add the following below this CDDL HEADER, with the 1612256Sgoetz * fields enclosed by brackets "[]" replaced with your own identifying 1712256Sgoetz * information: Portions Copyright [yyyy] [name of copyright owner] 1812256Sgoetz * 1912256Sgoetz * CDDL HEADER END 2012256Sgoetz */ 2112256Sgoetz/* 2212256Sgoetz * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 2312256Sgoetz */ 2412256Sgoetz 2512256Sgoetz/* 2612256Sgoetz * pcom: Print Comment 2712256Sgoetz * 2812256Sgoetz * This program demonstrates the use of the libelf interface to 2912256Sgoetz * read an ELF file. pcom will open an ELF file using 3012256Sgoetz * elf_begin(ELF_C_READ) and examine search the ELF file 3112256Sgoetz * for a .comment section. If a .comment section is found it's 3212256Sgoetz * contents will be displayed on stdout. 3312256Sgoetz */ 3412256Sgoetz 3512256Sgoetz#include <stdio.h> 3612256Sgoetz#include <libelf.h> 3712256Sgoetz#include <gelf.h> 3812256Sgoetz#include <fcntl.h> 3912256Sgoetz#include <unistd.h> 4012256Sgoetz#include <stdlib.h> 4112256Sgoetz#include <string.h> 4212256Sgoetz 4312256Sgoetz 4412256Sgoetzstatic const char *CommentStr = ".comment"; 4512256Sgoetz 4612256Sgoetzstatic void 4712256Sgoetzprint_comment(Elf *elf, const char *file) 4812256Sgoetz{ 4912256Sgoetz Elf_Scn *scn = NULL; 5012256Sgoetz GElf_Shdr shdr; 5112256Sgoetz Elf_Data *data; 5212256Sgoetz size_t shstrndx; 5312256Sgoetz 5412256Sgoetz 5512256Sgoetz (void) printf("%s .comment:\n", file); 5612256Sgoetz 5712256Sgoetz if (elf_getshdrstrndx(elf, &shstrndx) == -1) { 5812256Sgoetz (void) fprintf(stderr, "%s: elf_getshdrstrndx() failed: %s\n", 5912256Sgoetz file, elf_errmsg(0)); 6012256Sgoetz return; 6112256Sgoetz } 6212256Sgoetz 6312256Sgoetz while ((scn = elf_nextscn(elf, scn)) != NULL) { 6412256Sgoetz /* 6512256Sgoetz * Do a string compare to examine each section header 6612256Sgoetz * to see if it is a ".comment" section. If it is then 6712256Sgoetz * this is the section we want to process. 6812256Sgoetz */ 6912256Sgoetz if (gelf_getshdr(scn, &shdr) == NULL) { 7012256Sgoetz (void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n", 7112256Sgoetz file, elf_errmsg(0)); 7212256Sgoetz return; 7312256Sgoetz } 7412256Sgoetz if (strcmp(CommentStr, elf_strptr(elf, shstrndx, 7512256Sgoetz shdr.sh_name)) == 0) { 7612256Sgoetz int i; 7712256Sgoetz char *ptr; 7812256Sgoetz 7912256Sgoetz /* 8012256Sgoetz * Get the data associated with the .comment 8112256Sgoetz * section. 8212256Sgoetz */ 8312256Sgoetz if ((data = elf_getdata(scn, NULL)) == NULL) { 8412256Sgoetz (void) fprintf(stderr, 8512256Sgoetz "%s: elf_getdata() failed: %s\n", 8612256Sgoetz file, elf_errmsg(0)); 8712256Sgoetz return; 8812256Sgoetz } 8912256Sgoetz 9012256Sgoetz /* 9112256Sgoetz * Data in a .comment section is a list of 'null' 9212256Sgoetz * terminated strings. The following will print 9312256Sgoetz * one string per line. 9412256Sgoetz */ 9512256Sgoetz for (i = 0, ptr = (char *)data->d_buf; 9612256Sgoetz i < data->d_size; i++) 9712256Sgoetz if (ptr[i]) { 9812256Sgoetz (void) puts(&ptr[i]); 9912256Sgoetz i += strlen(&ptr[i]); 10012256Sgoetz } 10112256Sgoetz (void) putchar('\n'); 10212256Sgoetz } 10312256Sgoetz } 10412256Sgoetz 10512256Sgoetz} 10612256Sgoetz 10712256Sgoetzstatic void 10812256Sgoetzprocess_elf(Elf *elf, char *file, int fd, int member) 10912256Sgoetz{ 11012256Sgoetz Elf_Cmd cmd; 11112256Sgoetz Elf *_elf; 11212256Sgoetz 11312256Sgoetz switch (elf_kind(elf)) { 11412256Sgoetz case ELF_K_ELF: 11512256Sgoetz /* 11612256Sgoetz * This is an ELF file, now attempt to find it's 11712256Sgoetz * .comment section and to display it. 11812256Sgoetz */ 11912256Sgoetz print_comment(elf, file); 12012256Sgoetz break; 12112256Sgoetz case ELF_K_AR: 12212256Sgoetz /* 12312256Sgoetz * Archives contain multiple ELF files, which can each 12412256Sgoetz * in turn be examined with libelf. 12512256Sgoetz * 12612256Sgoetz * The below loop will iterate over each member of the 12712256Sgoetz * archive and recursively call process_elf(). 12812256Sgoetz */ 12912256Sgoetz cmd = ELF_C_READ; 13012256Sgoetz while ((_elf = elf_begin(fd, cmd, elf)) != NULL) { 13112256Sgoetz Elf_Arhdr *arhdr; 13212256Sgoetz char buffer[1024]; 13312256Sgoetz 13412256Sgoetz arhdr = elf_getarhdr(_elf); 13512256Sgoetz 13612256Sgoetz /* 13712256Sgoetz * Build up file names based off of 13812256Sgoetz * 'archivename(membername)'. 13912256Sgoetz */ 14012256Sgoetz (void) sprintf(buffer, "%s(%s)", file, arhdr->ar_name); 14112256Sgoetz 14212256Sgoetz /* 14312256Sgoetz * Recursively process the ELF members. 14412256Sgoetz */ 14512256Sgoetz process_elf(_elf, buffer, fd, 1); 14612256Sgoetz cmd = elf_next(_elf); 14712256Sgoetz (void) elf_end(_elf); 14812256Sgoetz } 14912256Sgoetz break; 15012256Sgoetz default: 15112256Sgoetz if (!member) 15212256Sgoetz (void) fprintf(stderr, 15312256Sgoetz "%s: unexpected elf_kind(): 0x%x\n", 15412256Sgoetz file, elf_kind(elf)); 15512256Sgoetz return; 15612256Sgoetz } 15712256Sgoetz} 15812256Sgoetz 15912256Sgoetzint 160main(int argc, char **argv) 161{ 162 int i; 163 164 if (argc < 2) { 165 (void) printf("usage: %s elf_file ...\n", argv[0]); 166 return (1); 167 } 168 169 /* 170 * Initialize the elf library, must be called before elf_begin() 171 * can be called. 172 */ 173 if (elf_version(EV_CURRENT) == EV_NONE) { 174 (void) fprintf(stderr, 175 "elf_version() failed: %s\n", elf_errmsg(0)); 176 return (1); 177 } 178 179 for (i = 1; i < argc; i++) { 180 int fd; 181 Elf *elf; 182 char *elf_fname; 183 184 elf_fname = argv[i]; 185 if ((fd = open(elf_fname, O_RDONLY)) == -1) { 186 perror("open"); 187 continue; 188 } 189 190 /* 191 * Attempt to open an Elf descriptor Read/Write 192 * for each file. 193 */ 194 if ((elf = elf_begin(fd, ELF_C_READ, 0)) == NULL) { 195 (void) fprintf(stderr, "elf_begin() failed: %s\n", 196 elf_errmsg(0)); 197 (void) close(fd); 198 continue; 199 } 200 201 /* 202 * Process each elf descriptor. 203 */ 204 process_elf(elf, elf_fname, fd, 0); 205 (void) elf_end(elf); 206 (void) close(fd); 207 } 208 209 return (0); 210} 211