Changeset View
Changeset View
Standalone View
Standalone View
contrib/elftoolchain/size/size.c
Show All 19 Lines | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <capsicum_helpers.h> | |||||
#include <err.h> | #include <err.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <gelf.h> | #include <gelf.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <libelftc.h> | #include <libelftc.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <libcasper.h> | |||||
#include <casper/cap_fileargs.h> | |||||
#include "_elftc.h" | #include "_elftc.h" | ||||
ELFTC_VCSID("$Id: size.c 3458 2016-05-09 15:01:25Z emaste $"); | ELFTC_VCSID("$Id: size.c 3458 2016-05-09 15:01:25Z emaste $"); | ||||
#define BUF_SIZE 1024 | #define BUF_SIZE 1024 | ||||
#define ELF_ALIGN(val,x) (((val)+(x)-1) & ~((x)-1)) | #define ELF_ALIGN(val,x) (((val)+(x)-1) & ~((x)-1)) | ||||
#define SIZE_VERSION_STRING "size 1.0" | #define SIZE_VERSION_STRING "size 1.0" | ||||
enum return_code { | enum return_code { | ||||
RETURN_OK, | RETURN_OK, | ||||
RETURN_NOINPUT, | |||||
RETURN_DATAERR, | RETURN_DATAERR, | ||||
RETURN_USAGE | RETURN_USAGE | ||||
}; | }; | ||||
enum output_style { | enum output_style { | ||||
STYLE_BERKELEY, | STYLE_BERKELEY, | ||||
STYLE_SYSV | STYLE_SYSV | ||||
}; | }; | ||||
enum radix_style { | enum radix_style { | ||||
RADIX_OCTAL, | RADIX_OCTAL, | ||||
RADIX_DECIMAL, | RADIX_DECIMAL, | ||||
RADIX_HEX | RADIX_HEX | ||||
}; | }; | ||||
static uint64_t bss_size, data_size, text_size, total_size; | static uint64_t bss_size, data_size, text_size, total_size; | ||||
static uint64_t bss_size_total, data_size_total, text_size_total; | static uint64_t bss_size_total, data_size_total, text_size_total; | ||||
static int show_totals; | static int show_totals; | ||||
static int size_option; | static int size_option; | ||||
static enum radix_style radix = RADIX_DECIMAL; | static enum radix_style radix = RADIX_DECIMAL; | ||||
static enum output_style style = STYLE_BERKELEY; | static enum output_style style = STYLE_BERKELEY; | ||||
static const char *default_args[2] = { "a.out", NULL }; | |||||
static struct { | static struct { | ||||
int row; | int row; | ||||
int col; | int col; | ||||
int *width; | int *width; | ||||
char ***tbl; | char ***tbl; | ||||
} *tb; | } *tb; | ||||
Show All 12 Lines | |||||
}; | }; | ||||
static void berkeley_calc(GElf_Shdr *); | static void berkeley_calc(GElf_Shdr *); | ||||
static void berkeley_footer(const char *, const char *, const char *); | static void berkeley_footer(const char *, const char *, const char *); | ||||
static void berkeley_header(void); | static void berkeley_header(void); | ||||
static void berkeley_totals(void); | static void berkeley_totals(void); | ||||
static int handle_core(char const *, Elf *elf, GElf_Ehdr *); | static int handle_core(char const *, Elf *elf, GElf_Ehdr *); | ||||
static void handle_core_note(Elf *, GElf_Ehdr *, GElf_Phdr *, char **); | static void handle_core_note(Elf *, GElf_Ehdr *, GElf_Phdr *, char **); | ||||
static int handle_elf(char const *); | static int handle_elf(int, char const *); | ||||
static void handle_phdr(Elf *, GElf_Ehdr *, GElf_Phdr *, uint32_t, | static void handle_phdr(Elf *, GElf_Ehdr *, GElf_Phdr *, uint32_t, | ||||
const char *); | const char *); | ||||
static void show_version(void); | static void show_version(void); | ||||
static void sysv_header(const char *, Elf_Arhdr *); | static void sysv_header(const char *, Elf_Arhdr *); | ||||
static void sysv_footer(void); | static void sysv_footer(void); | ||||
static void sysv_calc(Elf *, GElf_Ehdr *, GElf_Shdr *); | static void sysv_calc(Elf *, GElf_Ehdr *, GElf_Shdr *); | ||||
static void usage(void); | static void usage(void); | ||||
static void tbl_new(int); | static void tbl_new(int); | ||||
static void tbl_print(const char *, int); | static void tbl_print(const char *, int); | ||||
static void tbl_print_num(uint64_t, enum radix_style, int); | static void tbl_print_num(uint64_t, enum radix_style, int); | ||||
static void tbl_append(void); | static void tbl_append(void); | ||||
static void tbl_flush(void); | static void tbl_flush(void); | ||||
/* | /* | ||||
* size utility using elf(3) and gelf(3) API to list section sizes and | * size utility using elf(3) and gelf(3) API to list section sizes and | ||||
* total in elf files. Supports only elf files (core dumps in elf | * total in elf files. Supports only elf files (core dumps in elf | ||||
* included) that can be opened by libelf, other formats are not supported. | * included) that can be opened by libelf, other formats are not supported. | ||||
*/ | */ | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
int ch, r, rc; | cap_rights_t rights; | ||||
const char **files, *fn; | fileargs_t *fa; | ||||
int ch, fd, r, rc; | |||||
const char *fn; | |||||
char *defaultfn; | |||||
rc = RETURN_OK; | rc = RETURN_OK; | ||||
if (elf_version(EV_CURRENT) == EV_NONE) | if (elf_version(EV_CURRENT) == EV_NONE) | ||||
errx(EXIT_FAILURE, "ELF library initialization failed: %s", | errx(EXIT_FAILURE, "ELF library initialization failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
while ((ch = getopt_long(argc, argv, "ABVdhotx", size_longopts, | while ((ch = getopt_long(argc, argv, "ABVdhotx", size_longopts, | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | while ((ch = getopt_long(argc, argv, "ABVdhotx", size_longopts, | ||||
case '?': | case '?': | ||||
default: | default: | ||||
usage(); | usage(); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
files = (argc == 0) ? default_args : (void *) argv; | if (argc == 0) { | ||||
defaultfn = strdup("a.out"); | |||||
if (defaultfn == NULL) | |||||
err(EXIT_FAILURE, "strdup"); | |||||
argc = 1; | |||||
argv = &defaultfn; | |||||
} else { | |||||
defaultfn = NULL; | |||||
} | |||||
while ((fn = *files) != NULL) { | cap_rights_init(&rights, CAP_FSTAT, CAP_MMAP_R); | ||||
rc = handle_elf(fn); | fa = fileargs_init(argc, argv, O_RDONLY, 0, &rights, FA_OPEN); | ||||
if (fa == NULL) | |||||
err(EXIT_FAILURE, "failed to initialize fileargs"); | |||||
caph_cache_catpages(); | |||||
if (caph_limit_stdio() < 0) | |||||
err(EXIT_FAILURE, "failed to limit stdio rights"); | |||||
if (caph_enter_casper() < 0) | |||||
err(EXIT_FAILURE, "failed to enter capability mode"); | |||||
for (; argc > 0; argc--, argv++) { | |||||
fn = argv[0]; | |||||
fd = fileargs_open(fa, fn); | |||||
if (fd < 0) { | |||||
warn("%s: Failed to open", fn); | |||||
continue; | |||||
} | |||||
rc = handle_elf(fd, fn); | |||||
oshogbo: I guess here is the same problem with mmap. | |||||
Done Inline ActionsSee my comment in D21104. markj: See my comment in D21104. | |||||
if (rc != RETURN_OK) | if (rc != RETURN_OK) | ||||
warnx(rc == RETURN_NOINPUT ? | warnx("%s: File format not recognized", fn); | ||||
"'%s': No such file" : | |||||
"%s: File format not recognized", fn); | |||||
files++; | |||||
} | } | ||||
if (style == STYLE_BERKELEY) { | if (style == STYLE_BERKELEY) { | ||||
if (show_totals) | if (show_totals) | ||||
berkeley_totals(); | berkeley_totals(); | ||||
tbl_flush(); | tbl_flush(); | ||||
} | } | ||||
fileargs_free(fa); | |||||
Done Inline ActionsIf we are freeing defaultfn should we also close fileargs ? oshogbo: If we are freeing defaultfn should we also close fileargs ? | |||||
free(defaultfn); | |||||
return (rc); | return (rc); | ||||
} | } | ||||
static Elf_Data * | static Elf_Data * | ||||
xlatetom(Elf *elf, GElf_Ehdr *elfhdr, void *_src, void *_dst, | xlatetom(Elf *elf, GElf_Ehdr *elfhdr, void *_src, void *_dst, | ||||
Elf_Type type, size_t size) | Elf_Type type, size_t size) | ||||
{ | { | ||||
Elf_Data src, dst; | Elf_Data src, dst; | ||||
▲ Show 20 Lines • Show All 358 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Given an elf object,ar(1) filename, and based on the output style | * Given an elf object,ar(1) filename, and based on the output style | ||||
* and radix format the various sections and their length will be printed | * and radix format the various sections and their length will be printed | ||||
* or the size of the text, data, bss sections will be printed out. | * or the size of the text, data, bss sections will be printed out. | ||||
*/ | */ | ||||
static int | static int | ||||
handle_elf(char const *name) | handle_elf(int fd, const char *name) | ||||
{ | { | ||||
GElf_Ehdr elfhdr; | GElf_Ehdr elfhdr; | ||||
GElf_Shdr shdr; | GElf_Shdr shdr; | ||||
Elf *elf, *elf1; | Elf *elf, *elf1; | ||||
Elf_Arhdr *arhdr; | Elf_Arhdr *arhdr; | ||||
Elf_Scn *scn; | Elf_Scn *scn; | ||||
Elf_Cmd elf_cmd; | Elf_Cmd elf_cmd; | ||||
int exit_code, fd; | int exit_code; | ||||
if (name == NULL) | |||||
return (RETURN_NOINPUT); | |||||
if ((fd = open(name, O_RDONLY, 0)) < 0) | |||||
return (RETURN_NOINPUT); | |||||
elf_cmd = ELF_C_READ; | elf_cmd = ELF_C_READ; | ||||
elf1 = elf_begin(fd, elf_cmd, NULL); | elf1 = elf_begin(fd, elf_cmd, NULL); | ||||
while ((elf = elf_begin(fd, elf_cmd, elf1)) != NULL) { | while ((elf = elf_begin(fd, elf_cmd, elf1)) != NULL) { | ||||
arhdr = elf_getarhdr(elf); | arhdr = elf_getarhdr(elf); | ||||
if (elf_kind(elf) == ELF_K_NONE && arhdr == NULL) { | if (elf_kind(elf) == ELF_K_NONE && arhdr == NULL) { | ||||
(void) elf_end(elf); | (void) elf_end(elf); | ||||
(void) elf_end(elf1); | (void) elf_end(elf1); | ||||
▲ Show 20 Lines • Show All 322 Lines • Show Last 20 Lines |
I guess here is the same problem with mmap.