doc: remove duplicate LTTNG_UST_BLOCKING_RETRY_TIMEOUT man page entry
[lttng-ust.git] / liblttng-ust / lttng-ust-elf.c
index e90626906b6ea72c24d19bbcd4a3b7cee92e0821..663699b7ce91a5d9febf0d9903b64d042a580782 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <helper.h>
 #include <string.h>
 #include <lttng/align.h>
@@ -25,6 +26,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdbool.h>
 #include "lttng-tracer-core.h"
 
 #define BUF_LEN        4096
@@ -316,6 +318,18 @@ error:
        return NULL;
 }
 
+/*
+ * Test whether the ELF file is position independent code (PIC)
+ */
+uint8_t lttng_ust_elf_is_pic(struct lttng_ust_elf *elf)
+{
+       /*
+        * PIC has and e_type value of ET_DYN, see ELF specification
+        * version 1.1 p. 1-3.
+        */
+       return elf->ehdr->e_type == ET_DYN;
+}
+
 /*
  * Destroy the given lttng_ust_elf instance.
  */
@@ -342,7 +356,7 @@ void lttng_ust_elf_destroy(struct lttng_ust_elf *elf)
 int lttng_ust_elf_get_memsz(struct lttng_ust_elf *elf, uint64_t *memsz)
 {
        uint16_t i;
-       uint64_t _memsz = 0;
+       uint64_t low_addr = UINT64_MAX, high_addr = 0;
 
        if (!elf || !memsz) {
                goto error;
@@ -350,7 +364,6 @@ int lttng_ust_elf_get_memsz(struct lttng_ust_elf *elf, uint64_t *memsz)
 
        for (i = 0; i < elf->ehdr->e_phnum; ++i) {
                struct lttng_ust_elf_phdr *phdr;
-               uint64_t align;
 
                phdr = lttng_ust_elf_get_phdr(elf, i);
                if (!phdr) {
@@ -365,27 +378,19 @@ int lttng_ust_elf_get_memsz(struct lttng_ust_elf *elf, uint64_t *memsz)
                        goto next_loop;
                }
 
-               /*
-                * A p_align of 0 means no alignment, i.e. aligned to
-                * 1 byte.
-                */
-               align = phdr->p_align == 0 ? 1 : phdr->p_align;
-               /* Align the start of the segment. */
-               _memsz += offset_align(_memsz, align);
-               _memsz += phdr->p_memsz;
-               /*
-                * Add padding at the end of the segment, so it ends
-                * on a multiple of the align value (which usually
-                * means a page boundary). This makes the computation
-                * valid even in cases where p_align would change from
-                * one segment to the next.
-                */
-               _memsz += offset_align(_memsz, align);
+               low_addr = min_t(uint64_t, low_addr, phdr->p_vaddr);
+               high_addr = max_t(uint64_t, high_addr,
+                               phdr->p_vaddr + phdr->p_memsz);
        next_loop:
                free(phdr);
        }
 
-       *memsz = _memsz;
+       if (high_addr < low_addr) {
+               /* No PT_LOAD segments or corrupted data. */
+               goto error;
+       }
+
+       *memsz = high_addr - low_addr;
        return 0;
 error:
        return -1;
This page took 0.02568 seconds and 4 git commands to generate.