149d3bc9Richard Lowe/*
249d3bc9Richard Lowe
307dc194Richard Lowe  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
449d3bc9Richard Lowe
549d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
649d3bc9Richard Lowe  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
1449d3bc9Richard Lowe  free of the rightful claim of any third person regarding infringement
1549d3bc9Richard Lowe  or the like.  Any license provided herein, whether implied or
1649d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
1749d3bc9Richard Lowe  any, provided herein do not apply to combinations of this program with
1849d3bc9Richard Lowe  other software, or any other product whatsoever.
1949d3bc9Richard Lowe
2049d3bc9Richard Lowe  You should have received a copy of the GNU Lesser General Public
2149d3bc9Richard Lowe  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
2507dc194Richard Lowe  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2649d3bc9Richard Lowe  Mountain View, CA 94043, or:
2749d3bc9Richard Lowe
2849d3bc9Richard Lowe  http://www.sgi.com
2949d3bc9Richard Lowe
3049d3bc9Richard Lowe  For further information regarding this notice, see:
3149d3bc9Richard Lowe
3249d3bc9Richard Lowe  http://oss.sgi.com/projects/GenInfo/NoticeExplan
3349d3bc9Richard Lowe
3449d3bc9Richard Lowe*/
3549d3bc9Richard Lowe
3649d3bc9Richard Lowe
3749d3bc9Richard Lowe
3849d3bc9Richard Lowe#include "config.h"
3949d3bc9Richard Lowe#include "libdwarfdefs.h"
4049d3bc9Richard Lowe#include <stdio.h>
4149d3bc9Richard Lowe#include <string.h>
4249d3bc9Richard Lowe#include "pro_incl.h"
4349d3bc9Richard Lowe#include "pro_section.h"
4449d3bc9Richard Lowe#include "pro_macinfo.h"
4549d3bc9Richard Lowe
4649d3bc9Richard Lowe/*
4707dc194Richard Lowe        I don't much like the error strings this generates, since
4807dc194Richard Lowe        like the rest of libdwarf they are simple strings with
4907dc194Richard Lowe        no useful numbers in them. But that's not something I can
5007dc194Richard Lowe        fix without more work than I have time for
5107dc194Richard Lowe        right now.  davea Nov 94.
5249d3bc9Richard Lowe*/
5349d3bc9Richard Lowe
5449d3bc9Richard Lowe/* these are gross overestimates of the number of
5549d3bc9Richard Lowe** bytes needed to store a number in LEB form.
5649d3bc9Richard Lowe** Just estimates, and since blocks are reasonable size,
5749d3bc9Richard Lowe** the end-block waste is small.
5849d3bc9Richard Lowe** Of course the waste is NOT present on disk.
5949d3bc9Richard Lowe*/
6049d3bc9Richard Lowe
6149d3bc9Richard Lowe#define COMMAND_LEN ENCODE_SPACE_NEEDED
6249d3bc9Richard Lowe#define LINE_LEN    ENCODE_SPACE_NEEDED
6349d3bc9Richard Lowe#define BASE_MACINFO_MALLOC_LEN 2048
6449d3bc9Richard Lowe
6549d3bc9Richard Lowestatic int
6649d3bc9Richard Lowelibdwarf_compose_begin(Dwarf_P_Debug dbg, int code,
6707dc194Richard Lowe                       size_t maxlen, int *compose_error_type)
6849d3bc9Richard Lowe{
6949d3bc9Richard Lowe    unsigned char *nextchar;
7049d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
7149d3bc9Richard Lowe
7249d3bc9Richard Lowe    if (curblk == 0) {
7307dc194Richard Lowe        struct dw_macinfo_block_s *newb;
7407dc194Richard Lowe        size_t len;
7507dc194Richard Lowe
7607dc194Richard Lowe        /* initial allocation */
7707dc194Richard Lowe        size_t blen = BASE_MACINFO_MALLOC_LEN;
7807dc194Richard Lowe
7907dc194Richard Lowe        if (blen < maxlen) {
8007dc194Richard Lowe            blen = 2 * maxlen;
8107dc194Richard Lowe        }
8207dc194Richard Lowe        len = sizeof(struct dw_macinfo_block_s) + blen;
8307dc194Richard Lowe        newb =
8407dc194Richard Lowe            (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
8507dc194Richard Lowe        if (!newb) {
8607dc194Richard Lowe            *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
8707dc194Richard Lowe            return DW_DLV_ERROR;
8807dc194Richard Lowe        }
8907dc194Richard Lowe        newb->mb_data =
9007dc194Richard Lowe            (char *) newb + sizeof(struct dw_macinfo_block_s);
9107dc194Richard Lowe        newb->mb_avail_len = blen;
9207dc194Richard Lowe        newb->mb_used_len = 0;
9307dc194Richard Lowe        newb->mb_macinfo_data_space_len = blen;
9407dc194Richard Lowe        dbg->de_first_macinfo = newb;
9507dc194Richard Lowe        dbg->de_current_macinfo = newb;
9607dc194Richard Lowe        curblk = newb;
9749d3bc9Richard Lowe    } else if (curblk->mb_avail_len < maxlen) {
9807dc194Richard Lowe        struct dw_macinfo_block_s *newb;
9907dc194Richard Lowe        size_t len;
10007dc194Richard Lowe
10107dc194Richard Lowe        /* no space left in block: allocate a new block */
10207dc194Richard Lowe        size_t blen =
10307dc194Richard Lowe            dbg->de_current_macinfo->mb_macinfo_data_space_len * 2;
10407dc194Richard Lowe        if (blen < maxlen) {
10507dc194Richard Lowe            blen = 2 * maxlen;
10607dc194Richard Lowe        }
10707dc194Richard Lowe        len = sizeof(struct dw_macinfo_block_s) + blen;
10807dc194Richard Lowe        newb =
10907dc194Richard Lowe            (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
11007dc194Richard Lowe        if (!newb) {
11107dc194Richard Lowe            *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
11207dc194Richard Lowe            return DW_DLV_ERROR;
11307dc194Richard Lowe        }
11407dc194Richard Lowe        newb->mb_data =
11507dc194Richard Lowe            (char *) newb + sizeof(struct dw_macinfo_block_s);
11607dc194Richard Lowe        newb->mb_avail_len = blen;
11707dc194Richard Lowe        newb->mb_used_len = 0;
11807dc194Richard Lowe        newb->mb_macinfo_data_space_len = blen;
11907dc194Richard Lowe        dbg->de_first_macinfo->mb_next = newb;
12007dc194Richard Lowe        dbg->de_current_macinfo = newb;
12107dc194Richard Lowe        curblk = newb;
12249d3bc9Richard Lowe    }
12349d3bc9Richard Lowe    /* now curblk has enough room */
12449d3bc9Richard Lowe    dbg->de_compose_avail = curblk->mb_avail_len;
12549d3bc9Richard Lowe    dbg->de_compose_used_len = curblk->mb_used_len;
12649d3bc9Richard Lowe    nextchar =
12707dc194Richard Lowe        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
12849d3bc9Richard Lowe    *nextchar = code;
12949d3bc9Richard Lowe    dbg->de_compose_avail--;
13049d3bc9Richard Lowe    ++dbg->de_compose_used_len;
13149d3bc9Richard Lowe    return DW_DLV_OK;
13249d3bc9Richard Lowe}
13349d3bc9Richard Lowe
13449d3bc9Richard Lowe
13549d3bc9Richard Lowe
13649d3bc9Richard Lowestatic void
13749d3bc9Richard Lowelibdwarf_compose_add_string(Dwarf_P_Debug dbg, char *string, size_t len)
13849d3bc9Richard Lowe{
13949d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
14049d3bc9Richard Lowe    unsigned char *nextchar;
14149d3bc9Richard Lowe
14249d3bc9Richard Lowe    nextchar =
14307dc194Richard Lowe        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
14449d3bc9Richard Lowe
14507dc194Richard Lowe    len += 1;                   /* count the null terminator */
14649d3bc9Richard Lowe
14749d3bc9Richard Lowe    memcpy(nextchar, string, len);
14849d3bc9Richard Lowe    dbg->de_compose_avail -= len;
14949d3bc9Richard Lowe    dbg->de_compose_used_len += len;
15049d3bc9Richard Lowe    return;
15149d3bc9Richard Lowe
15249d3bc9Richard Lowe}
15349d3bc9Richard Lowestatic int
15449d3bc9Richard Lowelibdwarf_compose_add_line(Dwarf_P_Debug dbg,
15507dc194Richard Lowe                          Dwarf_Unsigned line, int *compose_error_type)
15649d3bc9Richard Lowe{
15749d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
15849d3bc9Richard Lowe    unsigned char *nextchar;
15949d3bc9Richard Lowe    int res;
16049d3bc9Richard Lowe    int nbytes;
16149d3bc9Richard Lowe
16249d3bc9Richard Lowe    nextchar =
16307dc194Richard Lowe        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
16449d3bc9Richard Lowe
16549d3bc9Richard Lowe    /* Put the created leb number directly into the macro buffer If
16649d3bc9Richard Lowe       dbg->de_compose_avail is > INT_MAX this will not work as the
16749d3bc9Richard Lowe       'int' will look negative to _dwarf_pro_encode_leb128_nm! */
16849d3bc9Richard Lowe
16949d3bc9Richard Lowe    res = _dwarf_pro_encode_leb128_nm(line, &nbytes,
17007dc194Richard Lowe                                      (char *) nextchar,
17107dc194Richard Lowe                                      (int) dbg->de_compose_avail);
17249d3bc9Richard Lowe    if (res != DW_DLV_OK) {
17307dc194Richard Lowe        *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
17407dc194Richard Lowe        return DW_DLV_ERROR;
17549d3bc9Richard Lowe    }
17649d3bc9Richard Lowe
17749d3bc9Richard Lowe    dbg->de_compose_avail -= nbytes;
17849d3bc9Richard Lowe    dbg->de_compose_used_len += nbytes;
17949d3bc9Richard Lowe    return DW_DLV_OK;
18049d3bc9Richard Lowe}
18149d3bc9Richard Lowe
18249d3bc9Richard Lowe/*
18349d3bc9Richard Lowe   This function actually 'commits' the space used by the
18449d3bc9Richard Lowe   preceeding calls.
18549d3bc9Richard Lowe*/
18649d3bc9Richard Lowestatic int
18749d3bc9Richard Lowelibdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type)
18849d3bc9Richard Lowe{
18949d3bc9Richard Lowe    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
19049d3bc9Richard Lowe
19149d3bc9Richard Lowe    if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) {
19207dc194Richard Lowe        *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
19307dc194Richard Lowe        return DW_DLV_ERROR;
19449d3bc9Richard Lowe    }
19549d3bc9Richard Lowe    curblk->mb_avail_len = dbg->de_compose_avail;
19649d3bc9Richard Lowe    curblk->mb_used_len = dbg->de_compose_used_len;
19749d3bc9Richard Lowe    return DW_DLV_OK;
19849d3bc9Richard Lowe}
19949d3bc9Richard Lowe
20049d3bc9Richard Lowe
20149d3bc9Richard Lowe
20249d3bc9Richard Loweint
20349d3bc9Richard Lowedwarf_def_macro(Dwarf_P_Debug dbg,
20407dc194Richard Lowe                Dwarf_Unsigned line,
20507dc194Richard Lowe                char *macname, char *macvalue, Dwarf_Error * error)
20649d3bc9Richard Lowe{
20749d3bc9Richard Lowe    size_t len;
20849d3bc9Richard Lowe    size_t len2;
20949d3bc9Richard Lowe    size_t length_est;
21049d3bc9Richard Lowe    int res;
21149d3bc9Richard Lowe    int compose_error_type;
21249d3bc9Richard Lowe
21349d3bc9Richard Lowe    if (dbg == NULL) {
21407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
21507dc194Richard Lowe        return (DW_DLV_ERROR);
21649d3bc9Richard Lowe    }
21749d3bc9Richard Lowe    if (macname == 0) {
21807dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
21907dc194Richard Lowe        return (DW_DLV_ERROR);
22049d3bc9Richard Lowe    }
22149d3bc9Richard Lowe    len = strlen(macname) + 1;
22249d3bc9Richard Lowe    if (len == 0) {
22307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
22407dc194Richard Lowe        return (DW_DLV_ERROR);
22549d3bc9Richard Lowe    }
22649d3bc9Richard Lowe    if (macvalue) {
22707dc194Richard Lowe        len2 = strlen(macvalue) + 1;
22849d3bc9Richard Lowe    } else {
22907dc194Richard Lowe        len2 = 0;
23007dc194Richard Lowe    }
23107dc194Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;       /* 1
23207dc194Richard Lowe                                                                   for
23307dc194Richard Lowe                                                                   space
23407dc194Richard Lowe                                                                   character
23507dc194Richard Lowe                                                                   we
23607dc194Richard Lowe                                                                   add */
23749d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est,
23807dc194Richard Lowe                                 &compose_error_type);
23949d3bc9Richard Lowe    if (res != DW_DLV_OK) {
24007dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
24107dc194Richard Lowe        return (DW_DLV_ERROR);
24249d3bc9Richard Lowe    }
24349d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
24449d3bc9Richard Lowe    if (res != DW_DLV_OK) {
24507dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
24607dc194Richard Lowe        return (DW_DLV_ERROR);
24749d3bc9Richard Lowe    }
24849d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, macname, len);
24949d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, " ", 1);
25049d3bc9Richard Lowe    if (macvalue) {
25107dc194Richard Lowe        libdwarf_compose_add_string(dbg, " ", 1);
25207dc194Richard Lowe        libdwarf_compose_add_string(dbg, macvalue, len2);
25349d3bc9Richard Lowe    }
25449d3bc9Richard Lowe    res = libdwarf_compose_complete(dbg, &compose_error_type);
25549d3bc9Richard Lowe    if (res != DW_DLV_OK) {
25607dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
25707dc194Richard Lowe        return (DW_DLV_ERROR);
25849d3bc9Richard Lowe    }
25949d3bc9Richard Lowe    return DW_DLV_OK;
26049d3bc9Richard Lowe}
26149d3bc9Richard Lowe
26249d3bc9Richard Loweint
26349d3bc9Richard Lowedwarf_undef_macro(Dwarf_P_Debug dbg,
26407dc194Richard Lowe                  Dwarf_Unsigned line,
26507dc194Richard Lowe                  char *macname, Dwarf_Error * error)
26649d3bc9Richard Lowe{
26749d3bc9Richard Lowe
26849d3bc9Richard Lowe    size_t len;
26949d3bc9Richard Lowe    size_t length_est;
27049d3bc9Richard Lowe    int res;
27149d3bc9Richard Lowe    int compose_error_type;
27249d3bc9Richard Lowe
27349d3bc9Richard Lowe    if (dbg == NULL) {
27407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
27507dc194Richard Lowe        return (DW_DLV_ERROR);
27649d3bc9Richard Lowe    }
27749d3bc9Richard Lowe    if (macname == 0) {
27807dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
27907dc194Richard Lowe        return (DW_DLV_ERROR);
28049d3bc9Richard Lowe    }
28149d3bc9Richard Lowe    len = strlen(macname) + 1;
28249d3bc9Richard Lowe    if (len == 0) {
28307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
28407dc194Richard Lowe        return (DW_DLV_ERROR);
28549d3bc9Richard Lowe    }
28649d3bc9Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + len;
28749d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est,
28807dc194Richard Lowe                                 &compose_error_type);
28949d3bc9Richard Lowe    if (res != DW_DLV_OK) {
29007dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
29107dc194Richard Lowe        return (DW_DLV_ERROR);
29249d3bc9Richard Lowe    }
29349d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
29449d3bc9Richard Lowe    if (res != DW_DLV_OK) {
29507dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
29607dc194Richard Lowe        return (DW_DLV_ERROR);
29749d3bc9Richard Lowe    }
29849d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, macname, len);
29949d3bc9Richard Lowe    res = libdwarf_compose_complete(dbg, &compose_error_type);
30049d3bc9Richard Lowe    if (res != DW_DLV_OK) {
30107dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
30207dc194Richard Lowe        return (DW_DLV_ERROR);
30349d3bc9Richard Lowe    }
30449d3bc9Richard Lowe    return DW_DLV_OK;
30549d3bc9Richard Lowe}
30649d3bc9Richard Lowe
30749d3bc9Richard Loweint
30849d3bc9Richard Lowedwarf_start_macro_file(Dwarf_P_Debug dbg,
30907dc194Richard Lowe                       Dwarf_Unsigned fileindex,
31007dc194Richard Lowe                       Dwarf_Unsigned linenumber, Dwarf_Error * error)
31149d3bc9Richard Lowe{
31249d3bc9Richard Lowe    size_t length_est;
31349d3bc9Richard Lowe    int res;
31449d3bc9Richard Lowe    int compose_error_type;
31549d3bc9Richard Lowe
31649d3bc9Richard Lowe    if (dbg == NULL) {
31707dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
31807dc194Richard Lowe        return (DW_DLV_ERROR);
31949d3bc9Richard Lowe    }
32049d3bc9Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + LINE_LEN;
32149d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est,
32207dc194Richard Lowe                                 &compose_error_type);
32349d3bc9Richard Lowe    if (res != DW_DLV_OK) {
32407dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
32507dc194Richard Lowe        return (DW_DLV_ERROR);
32649d3bc9Richard Lowe    }
32749d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, fileindex,
32807dc194Richard Lowe                                    &compose_error_type);
32949d3bc9Richard Lowe    if (res != DW_DLV_OK) {
33007dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
33107dc194Richard Lowe        return (DW_DLV_ERROR);
33249d3bc9Richard Lowe    }
33349d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, linenumber,
33407dc194Richard Lowe                                    &compose_error_type);
33549d3bc9Richard Lowe    if (res != DW_DLV_OK) {
33607dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
33707dc194Richard Lowe        return (DW_DLV_ERROR);
33849d3bc9Richard Lowe    }
33949d3bc9Richard Lowe    return DW_DLV_OK;
34049d3bc9Richard Lowe}
34149d3bc9Richard Lowe
34249d3bc9Richard Loweint
34349d3bc9Richard Lowedwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error)
34449d3bc9Richard Lowe{
34549d3bc9Richard Lowe    size_t length_est;
34649d3bc9Richard Lowe    int res;
34749d3bc9Richard Lowe    int compose_error_type;
34849d3bc9Richard Lowe
34949d3bc9Richard Lowe    if (dbg == NULL) {
35007dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
35107dc194Richard Lowe        return (DW_DLV_ERROR);
35249d3bc9Richard Lowe    }
35349d3bc9Richard Lowe    length_est = COMMAND_LEN;
35449d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est,
35507dc194Richard Lowe                                 &compose_error_type);
35649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
35707dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
35807dc194Richard Lowe        return (DW_DLV_ERROR);
35949d3bc9Richard Lowe    }
36049d3bc9Richard Lowe    res = libdwarf_compose_complete(dbg, &compose_error_type);
36149d3bc9Richard Lowe    if (res != DW_DLV_OK) {
36207dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
36307dc194Richard Lowe        return (DW_DLV_ERROR);
36449d3bc9Richard Lowe    }
36549d3bc9Richard Lowe    return DW_DLV_OK;
36649d3bc9Richard Lowe}
36749d3bc9Richard Lowe
36849d3bc9Richard Loweint
36949d3bc9Richard Lowedwarf_vendor_ext(Dwarf_P_Debug dbg,
37007dc194Richard Lowe                 Dwarf_Unsigned constant,
37107dc194Richard Lowe                 char *string, Dwarf_Error * error)
37249d3bc9Richard Lowe{
37349d3bc9Richard Lowe    size_t len;
37449d3bc9Richard Lowe    size_t length_est;
37549d3bc9Richard Lowe    int res;
37649d3bc9Richard Lowe    int compose_error_type;
37749d3bc9Richard Lowe
37849d3bc9Richard Lowe    if (dbg == NULL) {
37907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
38007dc194Richard Lowe        return (DW_DLV_ERROR);
38149d3bc9Richard Lowe    }
38249d3bc9Richard Lowe    if (string == 0) {
38307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
38407dc194Richard Lowe        return (DW_DLV_ERROR);
38549d3bc9Richard Lowe    }
38649d3bc9Richard Lowe    len = strlen(string) + 1;
38749d3bc9Richard Lowe    if (len == 0) {
38807dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
38907dc194Richard Lowe        return (DW_DLV_ERROR);
39049d3bc9Richard Lowe    }
39149d3bc9Richard Lowe    length_est = COMMAND_LEN + LINE_LEN + len;
39249d3bc9Richard Lowe    res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est,
39307dc194Richard Lowe                                 &compose_error_type);
39449d3bc9Richard Lowe    if (res != DW_DLV_OK) {
39507dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
39607dc194Richard Lowe        return (DW_DLV_ERROR);
39749d3bc9Richard Lowe    }
39849d3bc9Richard Lowe    res = libdwarf_compose_add_line(dbg, constant, &compose_error_type);
39949d3bc9Richard Lowe    if (res != DW_DLV_OK) {
40007dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
40107dc194Richard Lowe        return (DW_DLV_ERROR);
40249d3bc9Richard Lowe    }
40349d3bc9Richard Lowe    libdwarf_compose_add_string(dbg, string, len);
40449d3bc9Richard Lowe    libdwarf_compose_complete(dbg, &compose_error_type);
40549d3bc9Richard Lowe    if (res != DW_DLV_OK) {
40607dc194Richard Lowe        _dwarf_p_error(NULL, error, compose_error_type);
40707dc194Richard Lowe        return (DW_DLV_ERROR);
40849d3bc9Richard Lowe    }
40949d3bc9Richard Lowe    return DW_DLV_OK;
41049d3bc9Richard Lowe}
41149d3bc9Richard Lowe
41249d3bc9Richard Lowe
41349d3bc9Richard Lowe
41449d3bc9Richard Loweint
41549d3bc9Richard Lowe_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
41607dc194Richard Lowe                                        Dwarf_Error * error)
41749d3bc9Richard Lowe{
41849d3bc9Richard Lowe    /* Total num of bytes in .debug_macinfo section. */
41949d3bc9Richard Lowe    Dwarf_Unsigned mac_num_bytes;
42049d3bc9Richard Lowe
42149d3bc9Richard Lowe    /* Points to first byte of .debug_macinfo buffer. */
42249d3bc9Richard Lowe    Dwarf_Small *macinfo;
42349d3bc9Richard Lowe
42449d3bc9Richard Lowe    /* Fills in the .debug_macinfo buffer. */
42549d3bc9Richard Lowe    Dwarf_Small *macinfo_ptr;
42649d3bc9Richard Lowe
42749d3bc9Richard Lowe
42849d3bc9Richard Lowe    /* Used to scan the section data buffers. */
42949d3bc9Richard Lowe    struct dw_macinfo_block_s *m_prev;
43049d3bc9Richard Lowe    struct dw_macinfo_block_s *m_sect;
43149d3bc9Richard Lowe
43249d3bc9Richard Lowe
43349d3bc9Richard Lowe    /* Get the size of the debug_macinfo data */
43449d3bc9Richard Lowe    mac_num_bytes = 0;
43549d3bc9Richard Lowe    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
43607dc194Richard Lowe         m_sect = m_sect->mb_next) {
43707dc194Richard Lowe        mac_num_bytes += m_sect->mb_used_len;
43849d3bc9Richard Lowe    }
43949d3bc9Richard Lowe    /* Tthe final entry has a type code of 0 to indicate It is final
44049d3bc9Richard Lowe       for this CU Takes just 1 byte. */
44149d3bc9Richard Lowe    mac_num_bytes += 1;
44249d3bc9Richard Lowe
44349d3bc9Richard Lowe    GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
44407dc194Richard Lowe              macinfo, (unsigned long) mac_num_bytes, error);
44549d3bc9Richard Lowe    if (macinfo == NULL) {
44607dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
44707dc194Richard Lowe        return (0);
44849d3bc9Richard Lowe    }
44949d3bc9Richard Lowe
45049d3bc9Richard Lowe    macinfo_ptr = macinfo;
45149d3bc9Richard Lowe    m_prev = 0;
45249d3bc9Richard Lowe    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
45307dc194Richard Lowe         m_sect = m_sect->mb_next) {
45407dc194Richard Lowe        memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
45507dc194Richard Lowe        macinfo_ptr += m_sect->mb_used_len;
45607dc194Richard Lowe        if (m_prev) {
45707dc194Richard Lowe            _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
45807dc194Richard Lowe            m_prev = 0;
45907dc194Richard Lowe        }
46007dc194Richard Lowe        m_prev = m_sect;
46107dc194Richard Lowe    }
46207dc194Richard Lowe    *macinfo_ptr = 0;           /* the type code of 0 as last entry */
46349d3bc9Richard Lowe    if (m_prev) {
46407dc194Richard Lowe        _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
46507dc194Richard Lowe        m_prev = 0;
46649d3bc9Richard Lowe    }
46749d3bc9Richard Lowe
46849d3bc9Richard Lowe    dbg->de_first_macinfo = NULL;
46949d3bc9Richard Lowe    dbg->de_current_macinfo = NULL;
47049d3bc9Richard Lowe
47149d3bc9Richard Lowe    return (int) dbg->de_n_debug_sect;
47249d3bc9Richard Lowe}