149d3bc9Richard Lowe/*
207dc194Richard Lowe  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
34d9fdb4Robert Mustacchi  Portions Copyright 2011-2019 David Anderson.  All Rights Reserved.
449d3bc9Richard Lowe
549d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
64d9fdb4Robert Mustacchi  under the terms of version 2.1 of the GNU Lesser General Public License
749d3bc9Richard Lowe  as published by the Free Software Foundation.
849d3bc9Richard Lowe
949d3bc9Richard Lowe  This program is distributed in the hope that it would be useful, but
1049d3bc9Richard Lowe  WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc9Richard Lowe
1349d3bc9Richard Lowe  Further, this software is distributed without any warranty that it is
144d9fdb4Robert Mustacchi  free of the rightful claim of any third person regarding infringement
154d9fdb4Robert Mustacchi  or the like.  Any license provided herein, whether implied or
1649d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
174d9fdb4Robert Mustacchi  any, provided herein do not apply to combinations of this program with
184d9fdb4Robert Mustacchi  other software, or any other product whatsoever.
1949d3bc9Richard Lowe
204d9fdb4Robert Mustacchi  You should have received a copy of the GNU Lesser General Public
214d9fdb4Robert Mustacchi  License along with this program; if not, write the Free Software
2207dc194Richard Lowe  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2349d3bc9Richard Lowe  USA.
2449d3bc9Richard Lowe
2549d3bc9Richard Lowe*/
2649d3bc9Richard Lowe
2749d3bc9Richard Lowe#include "config.h"
2849d3bc9Richard Lowe#include "libdwarfdefs.h"
2949d3bc9Richard Lowe#include <stdio.h>
3049d3bc9Richard Lowe#include <string.h>
3149d3bc9Richard Lowe#include "pro_incl.h"
324d9fdb4Robert Mustacchi#include <stddef.h>
334d9fdb4Robert Mustacchi#include "dwarf.h"
344d9fdb4Robert Mustacchi#include "libdwarf.h"
354d9fdb4Robert Mustacchi#include "pro_opaque.h"
364d9fdb4Robert Mustacchi#include "pro_error.h"
374d9fdb4Robert Mustacchi#include "pro_encode_nm.h"
384d9fdb4Robert Mustacchi#include "pro_alloc.h"
3949d3bc9Richard Lowe#include "pro_section.h"
4049d3bc9Richard Lowe#include "pro_macinfo.h"
4149d3bc9Richard Lowe
424d9fdb4Robert Mustacchi/*  I don't much like the error strings this generates, since
434d9fdb4Robert Mustacchi    like the rest of libdwarf they are simple strings with
444d9fdb4Robert Mustacchi    no useful numbers in them. But that's not something I can
454d9fdb4Robert Mustacchi    fix without more work than I have time for
464d9fdb4Robert Mustacchi    right now.  davea Nov 94.
4749d3bc9Richard Lowe*/
4849d3bc9Richard Lowe
4949d3bc9Richard Lowe/* these are gross overestimates of the number of
5049d3bc9Richard Lowe** bytes needed to store a number in LEB form.
5149d3bc9Richard Lowe** Just estimates, and since blocks are reasonable size,
5249d3bc9Richard Lowe** the end-block waste is small.
5349d3bc9Richard Lowe** Of course the waste is NOT present on disk.
5449d3bc9Richard Lowe*/
5549d3bc9Richard Lowe
5649d3bc9Richard Lowe#define COMMAND_LEN ENCODE_SPACE_NEEDED
5749d3bc9Richard Lowe#define LINE_LEN    ENCODE_SPACE_NEEDED
5849d3bc9Richard Lowe#define BASE_MACINFO_MALLOC_LEN 2048
5949d3bc9Richard Lowe
6049d3bc9Richard Lowestatic int
6149d3bc9Richard Lowelibdwarf_compose_begin(Dwarf_P_Debug dbg, int code,
624d9fdb4Robert Mustacchi    size_t maxlen, int *compose_error_type)
6349d3bc9Richard Lowe{
6449d3bc9Richard Lowe    unsigned char *nextchar;
6549d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
6649d3bc9Richard Lowe
6749d3bc9Richard Lowe    if (curblk == 0) {
6807dc194Richard Lowe        struct dw_macinfo_block_s *newb;
6907dc194Richard Lowe        size_t len;
7007dc194Richard Lowe
7107dc194Richard Lowe        /* initial allocation */
7207dc194Richard Lowe        size_t blen = BASE_MACINFO_MALLOC_LEN;
7307dc194Richard Lowe
7407dc194Richard Lowe        if (blen < maxlen) {
7507dc194Richard Lowe            blen = 2 * maxlen;
7607dc194Richard Lowe        }
7707dc194Richard Lowe        len = sizeof(struct dw_macinfo_block_s) + blen;
7807dc194Richard Lowe        newb =
7907dc194Richard Lowe            (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
8007dc194Richard Lowe        if (!newb) {
8107dc194Richard Lowe            *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
8207dc194Richard Lowe            return DW_DLV_ERROR;
8307dc194Richard Lowe        }
8407dc194Richard Lowe        newb->mb_data =
8507dc194Richard Lowe            (char *) newb + sizeof(struct dw_macinfo_block_s);
8607dc194Richard Lowe        newb->mb_avail_len = blen;
8707dc194Richard Lowe        newb->mb_used_len = 0;
8807dc194Richard Lowe        newb->mb_macinfo_data_space_len = blen;
8907dc194Richard Lowe        dbg->de_first_macinfo = newb;
9007dc194Richard Lowe        dbg->de_current_macinfo = newb;
9107dc194Richard Lowe        curblk = newb;
9249d3bc9Richard Lowe    } else if (curblk->mb_avail_len < maxlen) {
9307dc194Richard Lowe        struct dw_macinfo_block_s *newb;
9407dc194Richard Lowe        size_t len;
9507dc194Richard Lowe
9607dc194Richard Lowe        /* no space left in block: allocate a new block */
9707dc194Richard Lowe        size_t blen =
9807dc194Richard Lowe            dbg->de_current_macinfo->mb_macinfo_data_space_len * 2;
9907dc194Richard Lowe        if (blen < maxlen) {
10007dc194Richard Lowe            blen = 2 * maxlen;
10107dc194Richard Lowe        }
10207dc194Richard Lowe        len = sizeof(struct dw_macinfo_block_s) + blen;
10307dc194Richard Lowe        newb =
10407dc194Richard Lowe            (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
10507dc194Richard Lowe        if (!newb) {
10607dc194Richard Lowe            *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
10707dc194Richard Lowe            return DW_DLV_ERROR;
10807dc194Richard Lowe        }
10907dc194Richard Lowe        newb->mb_data =
11007dc194Richard Lowe            (char *) newb + sizeof(struct dw_macinfo_block_s);
11107dc194Richard Lowe        newb->mb_avail_len = blen;
11207dc194Richard Lowe        newb->mb_used_len = 0;
11307dc194Richard Lowe        newb->mb_macinfo_data_space_len = blen;
11407dc194Richard Lowe        dbg->de_first_macinfo->mb_next = newb;
11507dc194Richard Lowe        dbg->de_current_macinfo = newb;
11607dc194Richard Lowe        curblk = newb;
11749d3bc9Richard Lowe    }
11849d3bc9Richard Lowe    /* now curblk has enough room */
11949d3bc9Richard Lowe    dbg->de_compose_avail = curblk->mb_avail_len;
12049d3bc9Richard Lowe    dbg->de_compose_used_len = curblk->mb_used_len;
12149d3bc9Richard Lowe    nextchar =
12207dc194Richard Lowe        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
12349d3bc9Richard Lowe    *nextchar = code;
12449d3bc9Richard Lowe    dbg->de_compose_avail--;
12549d3bc9Richard Lowe    ++dbg->de_compose_used_len;
12649d3bc9Richard Lowe    return DW_DLV_OK;
12749d3bc9Richard Lowe}
12849d3bc9Richard Lowe
12949d3bc9Richard Lowe
13049d3bc9Richard Lowe
13149d3bc9Richard Lowestatic void
1324d9fdb4Robert Mustacchilibdwarf_compose_add_string(Dwarf_P_Debug dbg, const char *string, size_t len)
13349d3bc9Richard Lowe{
13449d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
13549d3bc9Richard Lowe    unsigned char *nextchar;
13649d3bc9Richard Lowe
13749d3bc9Richard Lowe    nextchar =
13807dc194Richard Lowe        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
13949d3bc9Richard Lowe
14007dc194Richard Lowe    len += 1;                   /* count the null terminator */
14149d3bc9Richard Lowe
14249d3bc9Richard Lowe    memcpy(nextchar, string, len);
14349d3bc9Richard Lowe    dbg->de_compose_avail -= len;
14449d3bc9Richard Lowe    dbg->de_compose_used_len += len;
14549d3bc9Richard Lowe    return;
14649d3bc9Richard Lowe
14749d3bc9Richard Lowe}
14849d3bc9Richard Lowestatic int
14949d3bc9Richard Lowelibdwarf_compose_add_line(Dwarf_P_Debug dbg,
1504d9fdb4Robert Mustacchi    Dwarf_Unsigned line, int *compose_error_type)
15149d3bc9Richard Lowe{
15249d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
15349d3bc9Richard Lowe    unsigned char *nextchar;
15449d3bc9Richard Lowe    int res;
15549d3bc9Richard Lowe    int nbytes;
15649d3bc9Richard Lowe
15749d3bc9Richard Lowe    nextchar =
15807dc194Richard Lowe        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
15949d3bc9Richard Lowe
1604d9fdb4Robert Mustacchi    /*  Put the created leb number directly into the macro buffer If
1614d9fdb4Robert Mustacchi        dbg->de_compose_avail is > INT_MAX this will not work as the
1624d9fdb4Robert Mustacchi        'int' will look negative to _dwarf_pro_encode_leb128_nm! */
16349d3bc9Richard Lowe
16449d3bc9Richard Lowe    res = _dwarf_pro_encode_leb128_nm(line, &nbytes,
1654d9fdb4Robert Mustacchi        (char *) nextchar,
1664d9fdb4Robert Mustacchi        (int) dbg->de_compose_avail);
16749d3bc9Richard Lowe    if (res != DW_DLV_OK) {
16807dc194Richard Lowe        *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
16907dc194Richard Lowe        return DW_DLV_ERROR;
17049d3bc9Richard Lowe    }
17149d3bc9Richard Lowe
17249d3bc9Richard Lowe    dbg->de_compose_avail -= nbytes;
17349d3bc9Richard Lowe    dbg->de_compose_used_len += nbytes;
17449d3bc9Richard Lowe    return DW_DLV_OK;
17549d3bc9Richard Lowe}
17649d3bc9Richard Lowe
1774d9fdb4Robert Mustacchi/*  This function actually 'commits' the space used by the
1784d9fdb4Robert Mustacchi    preceeding calls.  */
17949d3bc9Richard Lowestatic int
18049d3bc9Richard Lowelibdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type)
18149d3bc9Richard Lowe{
18249d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
18349d3bc9Richard Lowe
18449d3bc9Richard Lowe    if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) {
18507dc194Richard Lowe        *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
18607dc194Richard Lowe        return DW_DLV_ERROR;
18749d3bc9Richard Lowe    }
18849d3bc9Richard Lowe    curblk->mb_avail_len = dbg->de_compose_avail;
18949d3bc9Richard Lowe    curblk->mb_used_len = dbg->de_compose_used_len;
19049d3bc9Richard Lowe    return DW_DLV_OK;
19149d3bc9Richard Lowe}
19249d3bc9Richard Lowe
19349d3bc9Richard Lowe
19449d3bc9Richard Lowe
19549d3bc9Richard Loweint
19649d3bc9Richard Lowedwarf_def_macro(Dwarf_P_Debug dbg,
1974d9fdb4Robert Mustacchi    Dwarf_Unsigned line,
1984d9fdb4Robert Mustacchi    char *macname, char *macvalue, Dwarf_Error * error)
19949d3bc9Richard Lowe{
20049d3bc9Richard Lowe    size_t len;
20149d3bc9Richard Lowe    size_t len2;
20249d3bc9Richard Lowe    size_t length_est;
20349d3bc9Richard Lowe    int res;
20449d3bc9Richard Lowe    int compose_error_type;
20549d3bc9Richard Lowe
20649d3bc9Richard Lowe    if (dbg == NULL) {
20707dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
20807dc194Richard Lowe        return (DW_DLV_ERROR);
20949d3bc9Richard Lowe    }
21049d3bc9Richard Lowe    if (macname == 0) {
21107dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
21207dc194Richard Lowe        return (DW_DLV_ERROR);
21349d3bc9Richard Lowe    }
21449d3bc9Richard Lowe    len = strlen(macname) + 1;
21549d3bc9Richard Lowe    if (len == 0) {
21607dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
21707dc194Richard Lowe        return (DW_DLV_ERROR);
21849d3bc9Richard Lowe    }
21949d3bc9Richard Lowe    if (macvalue) {
22007dc194Richard Lowe        len2 = strlen(macvalue) + 1;
22149d3bc9Richard Lowe    } else {
22207dc194Richard Lowe        len2 = 0;
22307dc194Richard Lowe    }
2244d9fdb4Robert Mustacchi
2254d9fdb4Robert Mustacchi    /* 1 for space character we add */
2264d9fdb4Robert Mustacchi    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;
2274d9fdb4Robert Mustacchi
22849d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est,
2294d9fdb4Robert Mustacchi        &compose_error_type);
23049d3bc9Richard Lowe    if (res != DW_DLV_OK) {
23107dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
23207dc194Richard Lowe        return (DW_DLV_ERROR);
23349d3bc9Richard Lowe    }
23449d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
23549d3bc9Richard Lowe    if (res != DW_DLV_OK) {
23607dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
23707dc194Richard Lowe        return (DW_DLV_ERROR);
23849d3bc9Richard Lowe    }
23949d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, macname, len);
24049d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, " ", 1);
24149d3bc9Richard Lowe    if (macvalue) {
24207dc194Richard Lowe        libdwarf_compose_add_string(dbg, " ", 1);
24307dc194Richard Lowe        libdwarf_compose_add_string(dbg, macvalue, len2);
24449d3bc9Richard Lowe    }
24549d3bc9Richard Lowe    res = libdwarf_compose_complete(dbg, &compose_error_type);
24649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
24707dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
24807dc194Richard Lowe        return (DW_DLV_ERROR);
24949d3bc9Richard Lowe    }
25049d3bc9Richard Lowe    return DW_DLV_OK;
25149d3bc9Richard Lowe}
25249d3bc9Richard Lowe
25349d3bc9Richard Loweint
25449d3bc9Richard Lowedwarf_undef_macro(Dwarf_P_Debug dbg,
2554d9fdb4Robert Mustacchi    Dwarf_Unsigned line,
2564d9fdb4Robert Mustacchi    char *macname, Dwarf_Error * error)
25749d3bc9Richard Lowe{
25849d3bc9Richard Lowe
25949d3bc9Richard Lowe    size_t len;
26049d3bc9Richard Lowe    size_t length_est;
26149d3bc9Richard Lowe    int res;
26249d3bc9Richard Lowe    int compose_error_type;
26349d3bc9Richard Lowe
26449d3bc9Richard Lowe    if (dbg == NULL) {
26507dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
26607dc194Richard Lowe        return (DW_DLV_ERROR);
26749d3bc9Richard Lowe    }
26849d3bc9Richard Lowe    if (macname == 0) {
26907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
27007dc194Richard Lowe        return (DW_DLV_ERROR);
27149d3bc9Richard Lowe    }
27249d3bc9Richard Lowe    len = strlen(macname) + 1;
27349d3bc9Richard Lowe    if (len == 0) {
27407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
27507dc194Richard Lowe        return (DW_DLV_ERROR);
27649d3bc9Richard Lowe    }
27749d3bc9Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + len;
27849d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est,
2794d9fdb4Robert Mustacchi        &compose_error_type);
28049d3bc9Richard Lowe    if (res != DW_DLV_OK) {
28107dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
28207dc194Richard Lowe        return (DW_DLV_ERROR);
28349d3bc9Richard Lowe    }
28449d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
28549d3bc9Richard Lowe    if (res != DW_DLV_OK) {
28607dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
28707dc194Richard Lowe        return (DW_DLV_ERROR);
28849d3bc9Richard Lowe    }
28949d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, macname, len);
29049d3bc9Richard Lowe    res = libdwarf_compose_complete(dbg, &compose_error_type);
29149d3bc9Richard Lowe    if (res != DW_DLV_OK) {
29207dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
29307dc194Richard Lowe        return (DW_DLV_ERROR);
29449d3bc9Richard Lowe    }
29549d3bc9Richard Lowe    return DW_DLV_OK;
29649d3bc9Richard Lowe}
29749d3bc9Richard Lowe
29849d3bc9Richard Loweint
29949d3bc9Richard Lowedwarf_start_macro_file(Dwarf_P_Debug dbg,
3004d9fdb4Robert Mustacchi    Dwarf_Unsigned fileindex,
3014d9fdb4Robert Mustacchi    Dwarf_Unsigned linenumber, Dwarf_Error * error)
30249d3bc9Richard Lowe{
30349d3bc9Richard Lowe    size_t length_est;
30449d3bc9Richard Lowe    int res;
30549d3bc9Richard Lowe    int compose_error_type;
30649d3bc9Richard Lowe
30749d3bc9Richard Lowe    if (dbg == NULL) {
30807dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
30907dc194Richard Lowe        return (DW_DLV_ERROR);
31049d3bc9Richard Lowe    }
31149d3bc9Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + LINE_LEN;
31249d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est,
3134d9fdb4Robert Mustacchi        &compose_error_type);
31449d3bc9Richard Lowe    if (res != DW_DLV_OK) {
31507dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
31607dc194Richard Lowe        return (DW_DLV_ERROR);
31749d3bc9Richard Lowe    }
31849d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, fileindex,
3194d9fdb4Robert Mustacchi        &compose_error_type);
32049d3bc9Richard Lowe    if (res != DW_DLV_OK) {
32107dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
32207dc194Richard Lowe        return (DW_DLV_ERROR);
32349d3bc9Richard Lowe    }
32449d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, linenumber,
3254d9fdb4Robert Mustacchi        &compose_error_type);
32649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
32707dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
32807dc194Richard Lowe        return (DW_DLV_ERROR);
32949d3bc9Richard Lowe    }
33049d3bc9Richard Lowe    return DW_DLV_OK;
33149d3bc9Richard Lowe}
33249d3bc9Richard Lowe
33349d3bc9Richard Loweint
33449d3bc9Richard Lowedwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error)
33549d3bc9Richard Lowe{
33649d3bc9Richard Lowe    size_t length_est;
33749d3bc9Richard Lowe    int res;
33849d3bc9Richard Lowe    int compose_error_type;
33949d3bc9Richard Lowe
34049d3bc9Richard Lowe    if (dbg == NULL) {
34107dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
34207dc194Richard Lowe        return (DW_DLV_ERROR);
34349d3bc9Richard Lowe    }
34449d3bc9Richard Lowe    length_est = COMMAND_LEN;
34549d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est,
3464d9fdb4Robert Mustacchi        &compose_error_type);
3474d9fdb4Robert Mustacchi    if (res == DW_DLV_ERROR) {
3484d9fdb4Robert Mustacchi        _dwarf_p_error(dbg, error, compose_error_type);
34907dc194Richard Lowe        return (DW_DLV_ERROR);
35049d3bc9Richard Lowe    }
35149d3bc9Richard Lowe    res = libdwarf_compose_complete(dbg, &compose_error_type);
3524d9fdb4Robert Mustacchi    if (res == DW_DLV_ERROR) {
3534d9fdb4Robert Mustacchi        _dwarf_p_error(dbg, error, compose_error_type);
3544d9fdb4Robert Mustacchi        return res;
35549d3bc9Richard Lowe    }
3564d9fdb4Robert Mustacchi    return res;
35749d3bc9Richard Lowe}
35849d3bc9Richard Lowe
35949d3bc9Richard Loweint
36049d3bc9Richard Lowedwarf_vendor_ext(Dwarf_P_Debug dbg,
3614d9fdb4Robert Mustacchi    Dwarf_Unsigned constant,
3624d9fdb4Robert Mustacchi    char *string, Dwarf_Error * error)
36349d3bc9Richard Lowe{
36449d3bc9Richard Lowe    size_t len;
36549d3bc9Richard Lowe    size_t length_est;
36649d3bc9Richard Lowe    int res;
36749d3bc9Richard Lowe    int compose_error_type;
36849d3bc9Richard Lowe
36949d3bc9Richard Lowe    if (dbg == NULL) {
37007dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
37107dc194Richard Lowe        return (DW_DLV_ERROR);
37249d3bc9Richard Lowe    }
37349d3bc9Richard Lowe    if (string == 0) {
37407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
37507dc194Richard Lowe        return (DW_DLV_ERROR);
37649d3bc9Richard Lowe    }
37749d3bc9Richard Lowe    len = strlen(string) + 1;
37849d3bc9Richard Lowe    if (len == 0) {
37907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
38007dc194Richard Lowe        return (DW_DLV_ERROR);
38149d3bc9Richard Lowe    }
38249d3bc9Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + len;
38349d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est,
3844d9fdb4Robert Mustacchi        &compose_error_type);
38549d3bc9Richard Lowe    if (res != DW_DLV_OK) {
38607dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
38707dc194Richard Lowe        return (DW_DLV_ERROR);
38849d3bc9Richard Lowe    }
38949d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, constant, &compose_error_type);
39049d3bc9Richard Lowe    if (res != DW_DLV_OK) {
39107dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
39207dc194Richard Lowe        return (DW_DLV_ERROR);
39349d3bc9Richard Lowe    }
39449d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, string, len);
39549d3bc9Richard Lowe    libdwarf_compose_complete(dbg, &compose_error_type);
39649d3bc9Richard Lowe    return DW_DLV_OK;
39749d3bc9Richard Lowe}
39849d3bc9Richard Lowe
39949d3bc9Richard Lowe
40049d3bc9Richard Lowe
40149d3bc9Richard Loweint
40249d3bc9Richard Lowe_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
4034d9fdb4Robert Mustacchi    Dwarf_Signed *nbufs,
4044d9fdb4Robert Mustacchi    Dwarf_Error * error)
40549d3bc9Richard Lowe{
40649d3bc9Richard Lowe    /* Total num of bytes in .debug_macinfo section. */
40749d3bc9Richard Lowe    Dwarf_Unsigned mac_num_bytes;
40849d3bc9Richard Lowe
40949d3bc9Richard Lowe    /* Points to first byte of .debug_macinfo buffer. */
41049d3bc9Richard Lowe    Dwarf_Small *macinfo;
41149d3bc9Richard Lowe
41249d3bc9Richard Lowe    /* Fills in the .debug_macinfo buffer. */
41349d3bc9Richard Lowe    Dwarf_Small *macinfo_ptr;
41449d3bc9Richard Lowe
41549d3bc9Richard Lowe
41649d3bc9Richard Lowe    /* Used to scan the section data buffers. */
41749d3bc9Richard Lowe    struct dw_macinfo_block_s *m_prev;
41849d3bc9Richard Lowe    struct dw_macinfo_block_s *m_sect;
41949d3bc9Richard Lowe
42049d3bc9Richard Lowe
42149d3bc9Richard Lowe    /* Get the size of the debug_macinfo data */
42249d3bc9Richard Lowe    mac_num_bytes = 0;
42349d3bc9Richard Lowe    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
4244d9fdb4Robert Mustacchi        m_sect = m_sect->mb_next) {
42507dc194Richard Lowe        mac_num_bytes += m_sect->mb_used_len;
42649d3bc9Richard Lowe    }
4274d9fdb4Robert Mustacchi    /*  The final entry has a type code of 0 to indicate It is final
4284d9fdb4Robert Mustacchi        for this CU Takes just 1 byte. */
42949d3bc9Richard Lowe    mac_num_bytes += 1;
43049d3bc9Richard Lowe
43149d3bc9Richard Lowe    GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
4324d9fdb4Robert Mustacchi        macinfo, (unsigned long) mac_num_bytes, error);
43349d3bc9Richard Lowe
43449d3bc9Richard Lowe    macinfo_ptr = macinfo;
43549d3bc9Richard Lowe    m_prev = 0;
43649d3bc9Richard Lowe    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
4374d9fdb4Robert Mustacchi        m_sect = m_sect->mb_next) {
43807dc194Richard Lowe        memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
43907dc194Richard Lowe        macinfo_ptr += m_sect->mb_used_len;
44007dc194Richard Lowe        if (m_prev) {
44107dc194Richard Lowe            _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
44207dc194Richard Lowe            m_prev = 0;
44307dc194Richard Lowe        }
44407dc194Richard Lowe        m_prev = m_sect;
44507dc194Richard Lowe    }
44607dc194Richard Lowe    *macinfo_ptr = 0;           /* the type code of 0 as last entry */
44749d3bc9Richard Lowe    if (m_prev) {
44807dc194Richard Lowe        _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
44907dc194Richard Lowe        m_prev = 0;
45049d3bc9Richard Lowe    }
45149d3bc9Richard Lowe
45249d3bc9Richard Lowe    dbg->de_first_macinfo = NULL;
45349d3bc9Richard Lowe    dbg->de_current_macinfo = NULL;
45449d3bc9Richard Lowe
4554d9fdb4Robert Mustacchi    *nbufs = dbg->de_n_debug_sect;
4564d9fdb4Robert Mustacchi    return DW_DLV_OK;
45749d3bc9Richard Lowe}