summaryrefslogtreecommitdiffstats
path: root/rtemstoolkit/elftoolchain/libdwarf/libdwarf_macinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'rtemstoolkit/elftoolchain/libdwarf/libdwarf_macinfo.c')
-rw-r--r--rtemstoolkit/elftoolchain/libdwarf/libdwarf_macinfo.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/rtemstoolkit/elftoolchain/libdwarf/libdwarf_macinfo.c b/rtemstoolkit/elftoolchain/libdwarf/libdwarf_macinfo.c
new file mode 100644
index 0000000..1c9101c
--- /dev/null
+++ b/rtemstoolkit/elftoolchain/libdwarf/libdwarf_macinfo.c
@@ -0,0 +1,254 @@
+/*-
+ * Copyright (c) 2009-2011 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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
+ * SUCH DAMAGE.
+ */
+
+#include "_libdwarf.h"
+
+ELFTC_VCSID("$Id: libdwarf_macinfo.c 2974 2013-12-23 06:46:22Z kaiwang27 $");
+
+#define _FILEINDEX_STACK_SIZE 16384
+
+static int
+_dwarf_macinfo_parse(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *off,
+ Dwarf_Macro_Details *dmd, Dwarf_Unsigned *cnt, Dwarf_Error *error)
+{
+ Dwarf_Unsigned lineno;
+ Dwarf_Signed fileindex[_FILEINDEX_STACK_SIZE];
+ char *p;
+ int i, type, sp;
+
+ i = 0;
+ sp = 0;
+ fileindex[sp] = -1;
+ while (*off < ds->ds_size) {
+
+ if (dmd != NULL)
+ dmd[i].dmd_offset = *off;
+
+ type = dbg->read(ds->ds_data, off, 1);
+
+ if (dmd != NULL) {
+ dmd[i].dmd_type = type;
+ dmd[i].dmd_fileindex = fileindex[sp];
+ }
+
+ switch (type) {
+ case 0:
+ break;
+ case DW_MACINFO_define:
+ case DW_MACINFO_undef:
+ case DW_MACINFO_vendor_ext:
+ lineno = _dwarf_read_uleb128(ds->ds_data, off);
+ p = (char *) ds->ds_data;
+ if (dmd != NULL) {
+ dmd[i].dmd_lineno = lineno;
+ dmd[i].dmd_macro = p + *off;
+
+ }
+ while (p[(*off)++] != '\0')
+ ;
+ break;
+ case DW_MACINFO_start_file:
+ lineno = _dwarf_read_uleb128(ds->ds_data, off);
+ if (sp >= _FILEINDEX_STACK_SIZE - 1) {
+ assert(0);
+ }
+ fileindex[++sp] = _dwarf_read_uleb128(ds->ds_data, off);
+ if (dmd != NULL) {
+ dmd[i].dmd_lineno = lineno;
+ dmd[i].dmd_fileindex = fileindex[sp];
+ }
+ break;
+ case DW_MACINFO_end_file:
+ if (sp > 0) {
+ sp--;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ DWARF_SET_ERROR(dbg, error,
+ DW_DLE_DEBUG_MACRO_INCONSISTENT);
+ return (DW_DLE_DEBUG_MACRO_INCONSISTENT);
+ }
+
+ i++;
+
+ if (type == 0)
+ break;
+ }
+
+ if (cnt != NULL)
+ *cnt = i;
+
+ return (DW_DLE_NONE);
+}
+
+void
+_dwarf_macinfo_cleanup(Dwarf_Debug dbg)
+{
+ Dwarf_MacroSet ms, tms;
+
+ if (STAILQ_EMPTY(&dbg->dbg_mslist))
+ return;
+
+ STAILQ_FOREACH_SAFE(ms, &dbg->dbg_mslist, ms_next, tms) {
+ STAILQ_REMOVE(&dbg->dbg_mslist, ms, _Dwarf_MacroSet, ms_next);
+ if (ms->ms_mdlist)
+ free(ms->ms_mdlist);
+ free(ms);
+ }
+}
+
+int
+_dwarf_macinfo_init(Dwarf_Debug dbg, Dwarf_Error *error)
+{
+ Dwarf_MacroSet ms;
+ Dwarf_Unsigned cnt;
+ Dwarf_Section *ds;
+ uint64_t offset, entry_off;
+ int ret;
+
+ if ((ds = _dwarf_find_section(dbg, ".debug_macinfo")) == NULL)
+ return (DW_DLE_NONE);
+
+ offset = 0;
+ while (offset < ds->ds_size) {
+
+ entry_off = offset;
+
+ ret = _dwarf_macinfo_parse(dbg, ds, &offset, NULL, &cnt, error);
+ if (ret != DW_DLE_NONE)
+ return (ret);
+
+ if (cnt == 0)
+ break;
+
+ if ((ms = calloc(1, sizeof(struct _Dwarf_MacroSet))) == NULL) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
+ ret = DW_DLE_MEMORY;
+ goto fail_cleanup;
+ }
+ STAILQ_INSERT_TAIL(&dbg->dbg_mslist, ms, ms_next);
+
+ if ((ms->ms_mdlist = calloc(cnt, sizeof(Dwarf_Macro_Details)))
+ == NULL) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
+ ret = DW_DLE_MEMORY;
+ goto fail_cleanup;
+ }
+
+ ms->ms_cnt = cnt;
+
+ offset = entry_off;
+
+ ret = _dwarf_macinfo_parse(dbg, ds, &offset, ms->ms_mdlist,
+ NULL, error);
+
+ if (ret != DW_DLE_NONE) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
+ ret = DW_DLE_MEMORY;
+ goto fail_cleanup;
+ }
+ }
+
+ return (DW_DLE_NONE);
+
+fail_cleanup:
+
+ _dwarf_macinfo_cleanup(dbg);
+
+ return (ret);
+}
+
+int
+_dwarf_macinfo_gen(Dwarf_P_Debug dbg, Dwarf_Error *error)
+{
+ Dwarf_P_Section ds;
+ Dwarf_Macro_Details *md;
+ int i, ret;
+
+ if (dbg->dbgp_mdcnt == 0)
+ return (DW_DLE_NONE);
+
+ /* Create .debug_frame section. */
+ RCHECK(_dwarf_section_init(dbg, &ds, ".debug_macinfo", 0, error));
+
+ /* Write the list of Dwarf_Macro_Details. */
+ for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) {
+ md = &dbg->dbgp_mdlist[i];
+ md->dmd_offset = ds->ds_size;
+ RCHECK(WRITE_VALUE(md->dmd_type, 1));
+ switch (md->dmd_type) {
+ case DW_MACINFO_define:
+ case DW_MACINFO_undef:
+ case DW_MACINFO_vendor_ext:
+ RCHECK(WRITE_ULEB128(md->dmd_lineno));
+ assert(md->dmd_macro != NULL);
+ RCHECK(WRITE_STRING(md->dmd_macro));
+ break;
+ case DW_MACINFO_start_file:
+ RCHECK(WRITE_ULEB128(md->dmd_lineno));
+ RCHECK(WRITE_ULEB128(md->dmd_fileindex));
+ break;
+ case DW_MACINFO_end_file:
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ RCHECK(WRITE_VALUE(0, 1));
+
+ /* Inform application the creation of .debug_macinfo ELF section. */
+ RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error));
+
+ return (DW_DLE_NONE);
+
+gen_fail:
+ _dwarf_section_free(dbg, &ds);
+
+ return (ret);
+}
+
+void
+_dwarf_macinfo_pro_cleanup(Dwarf_P_Debug dbg)
+{
+ Dwarf_Macro_Details *md;
+ int i;
+
+ assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE);
+ if (dbg->dbgp_mdlist == NULL)
+ return;
+
+ assert(dbg->dbgp_mdcnt > 0);
+ for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) {
+ md = &dbg->dbgp_mdlist[i];
+ if (md->dmd_macro)
+ free(md->dmd_macro);
+ }
+ free(dbg->dbgp_mdlist);
+ dbg->dbgp_mdlist = NULL;
+ dbg->dbgp_mdcnt = 0;
+}