VHDL: Use a type, dependent on entity generics, for other entity ports/generics
As mentioned by user8352 in the
comments, VHDL-2008 indeed allows to solve the problem using an unconstrained array of
unconstrained elements. In a normal, non-generic package, I added this type declaration:

package memory_image_pkg is
    type image_t is array(natural range &lt;&gt;) of std_logic_vector;
end package;


Then, in the entity, this type can be constrained directly in the generic definition:

use work.memory_image_pkg.all;

entity memory is
    generic (
        DATA_WIDTH : natural;
        ADDR_WIDTH : natural;
        INIT_DATA  : image_t(0 to 2 ** ADDR_WIDTH - 1)(DATA_WIDTH - 1 downto 0) := (others =&gt; (others =&gt; '0'))
    );
    port (
        [...]
    );
end memory;


To generate an instance of this entity with an initialization image, it's easiest to create a bounded
constant and pass that to the generic map:

use work.memory_image_pkg.all;

architecture rtl of ram is
    constant INIT_DATA : image_t(0 to 65535)(7 downto 0) := (
        x"00",
        [...]
    );
begin
    mem: entity work.memory
        generic map (
            DATA_WIDTH =&gt; 8,
            ADDR_WIDTH =&gt; 16,
            INIT_DATA =&gt; INIT_DATA
        )
        port map (
            [...]
        );
end rtl;